From: sparky4 Date: Mon, 21 Dec 2015 16:08:03 +0000 (-0600) Subject: wwww X-Git-Url: http://4ch.mooo.com/gitweb/?a=commitdiff_plain;h=75a35fd2843da7105acc7eee68674131431d0ccb;p=16.git wwww --- diff --git a/16.exe b/16.exe index 46a5d4c8..b6f2dbe7 100755 Binary files a/16.exe and b/16.exe differ diff --git a/16/x/default.fnt b/16/x/default.fnt new file mode 100755 index 00000000..12eb22cb --- /dev/null +++ b/16/x/default.fnt @@ -0,0 +1,260 @@ +; +; MODEX library default font +; Copyright (c) 1993-1994 by Alessandro Scotti +; + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0 + DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1 + DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2 + DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3 + DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4 + DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5 + DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6 + DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7 + DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8 + DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9 + DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10 + DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11 + DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12 + DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13 + DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14 + DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15 + DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16 + DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17 + DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18 + DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19 + DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20 + DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21 + DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22 + DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23 + DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24 + DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25 + DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26 + DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27 + DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28 + DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29 + DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30 + DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; + DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; ! + DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; " + DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; # + DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $ + DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; % + DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; & + DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; ' + DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; ( + DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; ) + DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; * + DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; + + DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; , + DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; - + DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; . + DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; / + DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0 + DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1 + DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2 + DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3 + DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4 + DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5 + DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6 + DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7 + DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8 + DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9 + DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; : + DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ; + DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; < + DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; = + DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; > + DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ? + DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @ + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A + DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B + DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C + DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F + DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G + DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H + DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I + DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J + DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K + DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L + DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M + DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N + DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O + DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P + DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q + DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R + DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S + DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T + DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U + DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V + DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W + DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X + DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y + DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z + DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [ + DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \ + DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ] + DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^ + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _ + DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; ` + DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a + DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b + DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c + DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d + DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e + DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g + DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h + DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i + DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j + DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k + DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l + DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m + DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n + DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o + DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q + DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r + DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s + DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t + DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u + DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v + DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w + DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x + DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y + DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z + DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; { + DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; | + DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; } + DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~ + DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ;  + DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128 + DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129 + DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130 + DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131 + DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132 + DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133 + DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134 + DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135 + DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136 + DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137 + DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138 + DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139 + DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140 + DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141 + DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142 + DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143 + DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144 + DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145 + DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146 + DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147 + DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148 + DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149 + DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150 + DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151 + DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152 + DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153 + DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154 + DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155 + DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156 + DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157 + DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158 + DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159 + DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160 + DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161 + DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162 + DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163 + DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164 + DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165 + DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166 + DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167 + DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168 + DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169 + DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170 + DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171 + DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172 + DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173 + DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174 + DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175 + DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176 + DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177 + DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178 + DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179 + DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180 + DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181 + DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182 + DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183 + DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184 + DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185 + DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186 + DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187 + DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188 + DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189 + DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190 + DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191 + DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192 + DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193 + DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194 + DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195 + DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196 + DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197 + DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198 + DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199 + DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200 + DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201 + DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202 + DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203 + DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204 + DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205 + DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206 + DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207 + DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208 + DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209 + DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210 + DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211 + DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212 + DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213 + DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214 + DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215 + DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216 + DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217 + DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218 + DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219 + DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220 + DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221 + DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222 + DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223 + DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224 + DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225 + DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226 + DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227 + DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228 + DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229 + DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230 + DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231 + DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232 + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233 + DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234 + DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235 + DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236 + DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237 + DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238 + DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239 + DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240 + DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241 + DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242 + DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243 + DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244 + DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245 + DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246 + DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247 + DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248 + DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249 + DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250 + DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251 + DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252 + DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253 + DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255 diff --git a/16/x/makefile b/16/x/makefile new file mode 100755 index 00000000..8ad2f244 --- /dev/null +++ b/16/x/makefile @@ -0,0 +1,81 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +LIBINCS = MODEX.DEF + +LIBOBJS = MXBB.OBJ \ + MXCC.OBJ \ + MXCG.OBJ \ + MXCL.OBJ \ + MXCR.OBJ \ + MXFB.OBJ \ + MXFP.OBJ \ + MXGC.OBJ \ + MXGI.OBJ \ + MXGM.OBJ \ + MXGP.OBJ \ + MXGV.OBJ \ + MXHL.OBJ \ + MXIT.OBJ \ + MXLL.OBJ \ + MXLN.OBJ \ + MXOT.OBJ \ + MXPB.OBJ \ + MXPF.OBJ \ + MXPG.OBJ \ + MXPI.OBJ \ + MXPN.OBJ \ + MXPP.OBJ \ + MXRA.OBJ \ + MXRP.OBJ \ + MXSA.OBJ \ + MXSC.OBJ \ + MXSI.OBJ \ + MXSL.OBJ \ + MXSM.OBJ \ + MXSP.OBJ \ + MXSS.OBJ \ + MXTL.OBJ \ + MXVS.OBJ \ + MXWD.OBJ \ + MXWM.OBJ \ + MXWP.OBJ \ + MXWR.OBJ + +# +# ASM compiler +# +ASMC = tasm +ASMO = /m5 /p + +# +# PAS compiler +# +PASC = tpc +PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = tlib + +.asm.obj: + $(ASMC) $(ASMO) $< + +target: modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/x/modex.def b/16/x/modex.def new file mode 100755 index 00000000..45bd900f --- /dev/null +++ b/16/x/modex.def @@ -0,0 +1,163 @@ +;------------------------------------------------------------ +; +; MODEX.DEF - Include file +; Copyright (c) 1993-1994 by Alessandro Scotti +; +JUMPS +LOCALS + +TRUE EQU 1 ; Boolean constants +FALSE EQU 0 + +USE286 = FALSE ; TRUE enables 80286 instructions +USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions + +IF USE286 EQ TRUE + P286 +ENDIF + +IF USE386 EQ TRUE + P386 + USE286 = TRUE +ENDIF + +MXVERSION EQU 0128h ; Library version (1.40) + +;------------------------------------------------------------ +; +; VGA definitions +; +MISC EQU 3C2h ; Miscellaneous output +TS EQU 3C4h ; Timing Sequencer index register +GDC EQU 3CEh ; Graphics Data Controller index register +CRTC EQU 3D4h ; CRTC index register +STATUS EQU 3DAh ; Input Status register one + +;------------------------------------------------------------ +; +; Raster operators +; +OP_SET EQU 0 +OP_MOVE EQU 0 ; Same as OP_SET +OP_AND EQU 1 +OP_OR EQU 2 +OP_XOR EQU 3 +OP_TRANS EQU 4 +OP_ADD EQU 5 ; Must be last op + +;------------------------------------------------------------ +; +; Polygon fill functions +; +POLYSCANBUFSIZE EQU 4*1024 + +;------------------------------------------------------------ +; Macro to push registers, variables or flags onto the stack +; Usage: .push "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.PUSH has more than 10 arguments> + ENDIF + IRP $reg, + IFB <$reg> ;; Is argument blank? + EXITM ;; Yes, exit + ELSEIFIDNI <$reg>, ;; Is argument the keyword "FLAGS"? + pushf ;; Yes, push flags + ELSE + push $reg ;; Push argument + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; Macro to pop registers, variables or flags from the stack +; Usage: .pop "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.POP has more than 10 arguments> + ENDIF + IRP $reg, + IFNB <$reg> ;; Is argument non-blank? + IFIDNI <$reg>, ;; Yes, is it the keyword "FLAGS"? + popf ;; Yes, pop flags + ELSE + pop $reg ;; Pop argument + ENDIF + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; +.enter MACRO localsize + IF USE286 EQ TRUE + enter localsize, 0 + ELSE + push bp + mov bp, sp + sub sp, localsize + ENDIF +ENDM + +;------------------------------------------------------------ +; +.leave MACRO argsize + IF USE286 EQ TRUE + leave + ELSE + mov sp, bp + pop bp + ENDIF + IFNB + ret argsize + ELSE + ret + ENDIF +ENDM + +;------------------------------------------------------------ +; +.shr MACRO arg, count + IF USE286 EQ TRUE + shr arg, count + ELSE + $temp = count + WHILE $temp GT 0 + shr arg, 1 + $temp = $temp-1 + ENDM + ENDIF +ENDM + +;------------------------------------------------------------ +; +.shl MACRO arg, count + IF USE286 EQ TRUE + shl arg, count + ELSE + $temp = count + WHILE $temp GT 0 + shl arg, 1 + $temp = $temp-1 + ENDM + ENDIF +ENDM + +;------------------------------------------------------------ +; +.chk386 MACRO name, jump + IF USE386 EQ FALSE + .OUT "Warning: ", , " needs a 386 or better to run!" + jmp @@jump + ENDIF +ENDM diff --git a/16/x/modex.h b/16/x/modex.h new file mode 100755 index 00000000..2c1f1ebe --- /dev/null +++ b/16/x/modex.h @@ -0,0 +1,153 @@ +/* + MODEX.H - C/C++ include file for the MODEX library + Copyright (c) 1994 Alessandro Scotti +*/ + +#ifndef _MODEX_H_ // Avoid nested inclusions +#define _MODEX_H_ + +// +// Video modes +// +#define MX_TEXT 0 // 80x25 text +#define MX_320x175 1 // 320x175x256 +#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5 +#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1 +#define MX_320x350 4 // 320x350x256 +#define MX_320x400 5 // 320x400x256, 2 pages +#define MX_320x480 6 // 320x480x256, 1 page +#define MX_360x175 7 // 360x175x256 +#define MX_360x200 8 // 360x200x256, 3 pages +#define MX_360x240 9 // 360x240x256, 2 pages +#define MX_360x350 10 // 360x350x256 +#define MX_360x400 11 // 360x400x256, 1 page +#define MX_360x480 12 // 360x480x256, 1 page +#define MX_400x600 13 // 400x600x256, 1 page + +// +// Fade effects +// +#define MX_FADEIN 0 +#define MX_FADEOUT 1 + +// +// Raster ops +// +#define OP_SET 0 // No operator +#define OP_AND 1 // And +#define OP_OR 2 // Or +#define OP_XOR 3 // Xor +#define OP_TRANS 4 // Transparent +#define OP_ADD 5 // Additive +#define OP_MOVE 0 // Alias for OP_SET + +// +// Temporary definitions +// +#define MXBYTE unsigned char +#define MXBOOL short int +#define MXSINT short int +#define MXUINT unsigned short int +#define MXAPI far pascal +#define MXPTR void far * + +// Functions + +#ifdef __cplusplus // Avoid C++ name mangling +extern "C" { +#endif + +// +// Initialization +// +MXSINT MXAPI mxInit( void ); // Returns 0 if successful +void MXAPI mxTerm( void ); +MXUINT MXAPI mxGetVersion( void ); +// +// Mode setting +// +void MXAPI mxChangeMode( MXUINT mode ); +void MXAPI mxSetMode( MXUINT mode ); +void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty ); +void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height ); +// +// Hardware support +// +void MXAPI mxWriteMode( MXBYTE wm ); +void MXAPI mxSplitScreen( MXUINT line ); +void MXAPI mxStartAddress( MXUINT sa ); +void MXAPI mxStartLine( MXUINT sl ); +void MXAPI mxWaitDisplay( void ); +void MXAPI mxWaitRetrace( void ); +void MXAPI mxWritePlane( MXBYTE wp ); +void MXAPI mxReadPlane( MXBYTE rp ); +void MXAPI mxRowAddress( MXBYTE ra ); +// +// Virtual screen +// +void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height ); +void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height ); +void MXAPI mxPan( MXUINT x, MXUINT y ); +// +// Clipping +// +MXBOOL MXAPI mxGetClip( void ); +MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h ); +MXBOOL MXAPI mxSetClip( MXBOOL ); +void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height ); +// +// Graphics +// +void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy ); +void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op ); +MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y ); +void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color ); +void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op ); +void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op ); +void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h ); +void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color ); +void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op ); +// +// Palette +// +void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b ); +void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue ); +void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT ); +void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step ); +// +// Text +// +MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight ); +void MXAPI mxSetTextColor( MXUINT color, MXUINT op ); +void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay ); +void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay ); +void MXAPI mxOutChar( MXSINT x, MXSINT y, char c ); +void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz ); +// +// Convex polygons +// +void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); + +#ifdef __cplusplus +} +#endif + +// +// Remove temporary defines +// +#undef MXBYTE +#undef MXBOOL +#undef MXSINT +#undef MXUINT +#undef MXPTR +#undef MXAPI + +#endif // _MODEX_H_ diff --git a/16/x/modex.lbr b/16/x/modex.lbr new file mode 100755 index 00000000..b1ec26b6 --- /dev/null +++ b/16/x/modex.lbr @@ -0,0 +1,38 @@ ++-MXBB.OBJ & ++-MXCC.OBJ & ++-MXCG.OBJ & ++-MXCL.OBJ & ++-MXCR.OBJ & ++-MXFB.OBJ & ++-MXFP.OBJ & ++-MXGC.OBJ & ++-MXGI.OBJ & ++-MXGM.OBJ & ++-MXGP.OBJ & ++-MXGV.OBJ & ++-MXHL.OBJ & ++-MXIT.OBJ & ++-MXLL.OBJ & ++-MXLN.OBJ & ++-MXOT.OBJ & ++-MXPB.OBJ & ++-MXPF.OBJ & ++-MXPG.OBJ & ++-MXPI.OBJ & ++-MXPN.OBJ & ++-MXPP.OBJ & ++-MXRA.OBJ & ++-MXRP.OBJ & ++-MXSA.OBJ & ++-MXSC.OBJ & ++-MXSI.OBJ & ++-MXSL.OBJ & ++-MXSM.OBJ & ++-MXSP.OBJ & ++-MXSS.OBJ & ++-MXTL.OBJ & ++-MXVS.OBJ & ++-MXWD.OBJ & ++-MXWM.OBJ & ++-MXWP.OBJ & ++-MXWR.OBJ diff --git a/16/x/modex.pas b/16/x/modex.pas new file mode 100755 index 00000000..7d9d26ed --- /dev/null +++ b/16/x/modex.pas @@ -0,0 +1,194 @@ +(* + Turbo Pascal interface to the MODEX library + Copyright (c) 1993,1994 by Alessandro Scotti +*) +unit ModeX; +interface + +const + (* Video modes *) + MX_TEXT = 0; + MX_320x175 = 1; + MX_320x200 = 2; + MX_320x240 = 3; + MX_320x350 = 4; + MX_320x400 = 5; + MX_320x480 = 6; + MX_360x175 = 7; + MX_360x200 = 8; + MX_360x240 = 9; + MX_360x350 = 10; + MX_360x400 = 11; + MX_360x480 = 12; + MX_400x600 = 13; + + (* Fade effects *) + MX_FADEIN = 0; + MX_FADEOUT = 1; + + (* Raster ops *) + OP_SET = 0; + OP_AND = 1; + OP_OR = 2; + OP_XOR = 3; + OP_TRANS = 4; + OP_ADD = 5; + OP_MOVE = 0; (* Alias for OP_SET *) + +procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer ); +procedure mxCircle( CX, CY: integer; Radius: word; Color: byte ); +procedure mxChangeMode( Mode: word ); +procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word ); +procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word ); +procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word ); +procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word ); +procedure mxGetAspect( var AspectX, AspectY: word ); +function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean; +function mxGetClip: boolean; +procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word ); +procedure mxGetPalette( Palette: pointer; Start, Count: word ); +function mxGetPixel( X, Y: word ): byte; +procedure mxGetScreenSize( var Width, Height: word ); +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); +function mxGetVersion: word; +procedure mxGetVirtualScreen( var Width, Height: word ); +procedure mxInit; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); +procedure mxOutChar( X, Y: integer; C: char ); +procedure mxOutText( X, Y: integer; S: pointer ); +procedure mxPan( X, Y: word ); +procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word ); +procedure mxPutPixel( X, Y: word; C: byte ); +procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxReadPlane( Plane: byte ); +procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer ); +procedure mxRowAddress( RowAddress: byte ); +function mxSetClip( Clip: boolean ): boolean; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); +procedure mxSetColor( Index, R, G, B: word ); +procedure mxSetFont( Font: pointer; Width, Height: word ); +procedure mxSetMode( Mode: word ); +procedure mxSetPalette( Palette: pointer; Start, Count: word ); +procedure mxSetTextColor( Color, Op: word ); +procedure mxSetTextStep( DeltaX, DeltaY: integer ); +procedure mxSetVirtualScreen( Width, Height: word ); +procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word ); +procedure mxSplitScreen( Line: word ); +procedure mxStartAddress( StartAddress: word ); +procedure mxStartLine( Line: word ); +procedure mxTerm; +procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxWaitDisplay; +procedure mxWaitRetrace; +procedure mxWriteMode( Mode: byte ); +procedure mxWritePlane( Plane: byte ); + +procedure mxFillPoly( Count: word; var Map, Points; Color: word ); +procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word ); +procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word ); + +procedure mxOutStr( X, Y: integer; S: string ); + +implementation + +procedure mxBitBlt; external; +procedure mxChangeMode( Mode: word ); external; +procedure mxCircle; external; +procedure mxColorToGray; external; +procedure mxFadePalette; external; +procedure mxFillBox; external; +procedure mxGammaCorrect; external; +procedure mxGetAspect( var AspectX, AspectY: word ); external; +function mxGetClipRegion; external; +function mxGetClip: boolean; external; +procedure mxGetImage; external; +procedure mxGetPalette( Palette: pointer; Start, Count: word ); external; +function mxGetPixel( X, Y: word ): byte; external; +procedure mxGetScreenSize( var Width, Height: word ); external; +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external; +function mxGetVersion: word; external; +procedure mxGetVirtualScreen( var Width, Height: word ); external; +procedure mxInit; external; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external; +procedure mxOutChar( X, Y: integer; C: char ); external; +procedure mxOutText( X, Y: integer; S: pointer ); external; +procedure mxPan( X, Y: word ); external; +procedure mxPutImage; external; +procedure mxPutPixel( X, Y: word; C: byte ); external; +procedure mxPutTile; external; +procedure mxReadPlane( Plane: byte ); external; +procedure mxRotatePalette; external; +procedure mxRowAddress( RowAddress: byte ); external; +function mxSetClip( Clip: boolean ): boolean; external; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external; +procedure mxSetColor( Index, R, G, B: word ); external; +procedure mxSetFont( Font: pointer; Width, Height: word ); external; +procedure mxSetMode( Mode: word ); external; +procedure mxSetPalette( Palette: pointer; Start, Count: word ); external; +procedure mxSetTextColor( Color, Op: word ); external; +procedure mxSetTextStep( DeltaX, DeltaY: integer ); external; +procedure mxSetVirtualScreen( Width, Height: word ); external; +procedure mxSplitScreen( Line: word ); external; +procedure mxStartAddress( StartAddress: word ); external; +procedure mxStartLine; external; +procedure mxStretchImage; external; +procedure mxTerm; external; +procedure mxTransPutTile; external; +procedure mxWaitDisplay; external; +procedure mxWaitRetrace; external; +procedure mxWriteMode( Mode: byte ); external; +procedure mxWritePlane( Plane: byte ); external; + +procedure mxFillPoly; external; +procedure mxGouraudPoly; external; +procedure mxTexturePoly; external; +{$L MXPB} +{$L MXPF} +{$L MXPG} +{$L MXPT} + +{$L MXBB} +{$L MXCC} +{$L MXCG} +{$L MXCL} +{$L MXCR} +{$L MXFB} +{$L MXFP} +{$L MXGI} +{$L MXGM} +{$L MXGP} +{$L MXGV} +{$L MXHL} +{$L MXIT} +{$L MXLN} +{$L MXOT} +{$L MXPI} +{$L MXPN} +{$L MXPP} +{$L MXRA} +{$L MXRP} +{$L MXSA} +{$L MXSC} +{$L MXSI} +{$L MXSL} +{$L MXSM} +{$L MXSP} +{$L MXSS} +{$L MXTL} +{$L MXVS} +{$L MXWD} +{$L MXWM} +{$L MXWP} +{$L MXWR} + +(* + Prints a Turbo Pascal string. + Note: BP 7.0 supports ASCIIZ strings (PChar type). +*) +procedure mxOutStr; +begin + S := S + #0; + mxOutText( X, Y, @S[1] ); +end; + +end. diff --git a/16/x/modex/DEMO01.EXE b/16/x/modex/DEMO01.EXE new file mode 100755 index 00000000..28caff88 Binary files /dev/null and b/16/x/modex/DEMO01.EXE differ diff --git a/16/x/modex/DEMO01.PAS b/16/x/modex/DEMO01.PAS new file mode 100755 index 00000000..c684acdd --- /dev/null +++ b/16/x/modex/DEMO01.PAS @@ -0,0 +1,126 @@ +(* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + MAX_SPRITE = 100; +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO02.EXE b/16/x/modex/DEMO02.EXE new file mode 100755 index 00000000..14e7dc72 Binary files /dev/null and b/16/x/modex/DEMO02.EXE differ diff --git a/16/x/modex/DEMO02.PAS b/16/x/modex/DEMO02.PAS new file mode 100755 index 00000000..6b4fb6f9 --- /dev/null +++ b/16/x/modex/DEMO02.PAS @@ -0,0 +1,125 @@ +(* + DEMO02 - Texture mapping and palette rotation + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Plasma, Threed; + +const + LSIZE = 85; + Trans : TPoint = ( X:0; Y:0; Z:0 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of T2DPoint; + Width : word; + Data : array[ 1..64*64 ] of byte; + end; + TQuad = record + VtxCnt : word; + Vtx : array[ 0..3 ] of word; + Texture: word; + end; +var + Vtx : array[ 0..7 ] of TPoint; + XVtx : array[ 0..7 ] of TPoint; + VVtx : array[ 0..7 ] of T2DPoint; + Face : array[ 0..5 ] of TQuad; + Txts : array[ 0..5 ] of TTexture; + Nrm : array[ 0..5 ] of TPoint; + XNrm : array[ 0..5 ] of TPoint; + Page : word; + Palette: array[ byte ] of record R, G, B: byte; end; + +(* Make a 64x64 plasma to be used as texture *) +procedure MakeTexture( Idx: word ); +var + I: word; +begin + mxFillBox( 0, 0, 64, 64, 0, OP_SET ); + MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 ); + mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 ); + (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *) + with Txts[Idx] do begin + Desc[0].X := $80; Desc[0].Y := $80; + Desc[1].X := $80; Desc[1].Y := $3F80; + Desc[2].X := $3F80; Desc[2].Y := $3F80; + Desc[3].X := $3F80; Desc[3].Y := $80; + Width := 64; + end; +end; + +procedure Init; +var + I: integer; +begin + (* Build vertexes for a cube *) + with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + for I:=0 to 7 do begin (* Make points 16:16 fixed *) + Vtx[I].X := Vtx[I].X*$10000; + Vtx[I].Y := Vtx[I].Y*$10000; + Vtx[I].Z := Vtx[I].Z*$10000; + end; + (* Build faces *) + with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end; + with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end; + with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end; + with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end; + with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end; + with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end; + for I:=0 to 5 do Face[I].Texture := I; + (* Build textures and palette *) + Randomize; + FillChar( Palette, SizeOf(Palette), 0 ); + MakePlasmaPalette( Palette, PAL_RGB ); + mxSetPalette( @Palette, 0, 193 ); + for I:=0 to 5 do MakeTexture( I ); +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, 8 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + mxRotatePalette( @Palette[1], 192, 3 ); (* Rotate palette *) + (* Draw cube: backface culling is straighforward in this case, so *) + (* it can be handled by the polygon filling procedure *) + for I:=0 to 5 do + mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width ); + mxStartLine( Page ); (* Flip pages *) + mxSetPalette( @Palette[1], 1, 192 ); (* Set new palette *) + Page := 240-Page; + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO03.EXE b/16/x/modex/DEMO03.EXE new file mode 100755 index 00000000..c646c4b0 Binary files /dev/null and b/16/x/modex/DEMO03.EXE differ diff --git a/16/x/modex/DEMO03.PAS b/16/x/modex/DEMO03.PAS new file mode 100755 index 00000000..01d10f49 --- /dev/null +++ b/16/x/modex/DEMO03.PAS @@ -0,0 +1,152 @@ +(* + DEMO03 - Simple star animation, morphs between a cube and a sphere + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 1000; (* Number of points *) + EDGE = 70; (* Length of cube edge *) + RADIUS = 90; (* Radius of sphere *) + WAITCOUNT = 192; (* Frames to wait for non-morphing shapes *) + MS = 32; (* Number of steps for morphing *) + Trans : TPoint = ( X:0; Y:0; Z:0 ); + InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 ); + InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS ); + InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 ); + InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 ); +type + T2DPoint = record + X, Y: integer; + end; + T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint; + P3DPointArray = ^T3DPointArray; +var + CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray; + VVtx : array[ 0..MAXVTX-1 ] of T2DPoint; + Page : word; + Status, Count, Delta1, Delta2, Morph1, Morph2: integer; + +procedure Swap( var A, B: longint ); +var + L: longint; +begin + L := A; A := B; B := L; +end; + +function Toggle( A: longint ): longint; +begin + Toggle := A; + if( Random(2) = 0 ) then Toggle := -A; +end; + +procedure Init; +label Retry; +var + I: integer; +begin + New( CubeVtx ); + New( SphereVtx ); + New( Vtx ); + New( XVtx ); + (* Build vertexes (yes, I know this piece of code is terrible) *) + Randomize; + for I:=0 to MAXVTX-1 do begin + with CubeVtx^[I] do begin + (* Build cube *) + X := (longint(Random(2*EDGE))-EDGE)*$10000; + Y := (longint(Random(2*EDGE))-EDGE)*$10000; + Z := Toggle( EDGE*$10000 ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + end; + with SphereVtx^[I] do begin + (* Build sphere *) +Retry: + X := (longint(Random(2*RADIUS))-RADIUS); + Y := (longint(Random(2*RADIUS))-RADIUS); + if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry; + Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + X := X * $10000; Y := Y * $10000; Z := Z * $10000; + end; + end; + (* Initialize morphing *) + Move( CubeVtx^, Vtx^, SizeOf(Vtx^) ); + Status := 0; + Count := WAITCOUNT; +end; + +procedure Morph; +var + I: integer; +begin + (* Fully unoptimized, slowest loop I could think of! *) + for I:=0 to MAXVTX-1 do begin + Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS; + Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS; + Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS; + end; +end; + +var + AX, AY, AZ: byte; + I: word; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + C := #0; + repeat + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx^, XVtx^, MAXVTX ); (* 3D transform points *) + tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw points *) + for I:=0 to MAXVTX-1 do + mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 ); + mxStartLine( Page ); (* Flip pages *) + Page := 240-Page; + (* Morph *) + if( Odd(Status) ) then begin + Morph; + Inc( Morph1, Delta1 ); + Inc( Morph2, Delta2 ); + if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status ); + if( Status = 4 ) then Status := 0; + end + else begin + Dec( Count ); + if( Count < 0 ) then begin + Inc( Status ); + Count := WAITCOUNT; + Morph1 := InitMorph1[Status]; + Morph2 := InitMorph2[Status]; + Delta1 := InitDelta1[Status]; + Delta2 := InitDelta2[Status]; + end; + end; + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO04.DAT b/16/x/modex/DEMO04.DAT new file mode 100755 index 00000000..72aaad08 Binary files /dev/null and b/16/x/modex/DEMO04.DAT differ diff --git a/16/x/modex/DEMO04.EXE b/16/x/modex/DEMO04.EXE new file mode 100755 index 00000000..1fec5e8a Binary files /dev/null and b/16/x/modex/DEMO04.EXE differ diff --git a/16/x/modex/DEMO04.PAS b/16/x/modex/DEMO04.PAS new file mode 100755 index 00000000..1a946315 --- /dev/null +++ b/16/x/modex/DEMO04.PAS @@ -0,0 +1,198 @@ +(* + DEMO04 - Multiple textures and triple buffering (3 pages) + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 256; + MAXCUB = 2; + MAXTXT = 2; + Trans : TPoint = ( X:0; Y:0; Z:0 ); + TxtSunDial: array[ 0..7 ] of word = ( + $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 ); + TxtSapphire : array[ 0..7 ] of word = ( + $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 ); + TxtMarble: array[ 0..7 ] of word = ( + $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of record X, Y: word end; + Width : word; + Data : pointer; + end; + TQuad = record + Vtx : array[ 0..3 ] of word; + Texture: word; + end; + TCube = record + Face : array[ 0..5 ] of TQuad; + Base : integer; + end; +var + Vtx, XVtx: array[ 0..MAXVTX ] of TPoint; + VVtx : array[ 0..MAXVTX ] of T2DPoint; + Cube : array[ 0..MAXCUB ] of TCube; + ZList : array[ 0..MAXCUB ] of integer; + VtxCnt : word; + Txts : array[ 0..MAXTXT ] of TTexture; + Page : word; + Palette : array[ byte ] of record R, G, B: byte; end; + TxtDat1, TxtDat2: pointer; + +(* Add a new entry to the vertex array *) +procedure AddVtx( PX, PY, PZ: longint ); +begin + with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end; + Inc( VtxCnt ); +end; + +procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer ); +const + FaceIdx: array[ 0..23 ] of integer = ( + 0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 ); +var + I, VC: integer; +begin + VC := VtxCnt; + C.Base := VC; + AddVtx( X1+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y2+TY, Z2+TZ ); + AddVtx( X1+TX, Y2+TY, Z2+TZ ); + for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I]; + for I:=0 to 5 do C.Face[I].Texture := Texture; +end; + +procedure MakeTexture( Idx: integer; var VtxData ); +var + P: ^word; + I: integer; +begin + P := @VtxData; + with Txts[Idx] do begin + for I:=0 to 3 do begin + Desc[I].X := P^; Inc( P ); + Desc[I].Y := P^; Inc( P ); + end; + Width := 129; + Data := TxtDat1; + end; +end; + +procedure Init; +var + I: integer; + V: integer; + F: file; + P: array[ 1..768 ] of byte; +begin + (* Initialize objects *) + VtxCnt := 0; + MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 ); (* Sundial *) + Cube[0].Face[0].Texture := 0; + V := VtxCnt; + MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *) + tdSetTranslation( Trans ); + tdSetRotation( 32, 32, 00 ); + tdRotate( Vtx[V], XVtx[V], 8 ); (* Got to rotate this cube *) + for I:=V to V+7 do begin + Vtx[I].X := XVtx[I].X; + Vtx[I].Y := XVtx[I].Y; + Vtx[I].Z := XVtx[I].Z + 100*$10000; + end; + MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *) + (* Load texture and palette *) + Assign( F, 'DEMO04.DAT' ); + Reset( F, 1 ); + BlockRead( F, P, SizeOf(P) ); + mxSetPalette( @P, 0, 256 ); + GetMem( TxtDat1, 63*1024 ); + BlockRead( F, TxtDat1^, 129*286 ); + Close( F ); + TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 ); + (* Init textures *) + MakeTexture( 0, TxtSundial ); + MakeTexture( 1, TxtMarble ); + MakeTexture( 2, TxtSapphire ); + Txts[2].Data := TxtDat2; +end; + +(* Sort procedure, not worth optimizing with only a few objects *) +procedure SortObjects; +var + I, J, K: integer; + ZMax: array[ 0..MAXCUB ] of longint; + ZI: integer; + L: longint; +begin + for I:=0 to MAXCUB do begin + L := XVtx[Cube[I].Base].Z; + for J:=1 to 7 do + if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z; + ZMax[I] := L; + ZList[I] := I; + end; + for I:=0 to MAXCUB-1 do begin + ZI := I; + for J:=I+1 to MAXCUB do + if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J; + if( ZI <> I ) then begin + K := ZList[I]; + ZList[I] := ZList[ZI]; + ZList[ZI] := K; + end; + end; +end; + +var + AX, AY, AZ: byte; + I, J, K: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + (* Init 3D transforms, perspective is intentionally exaggerated *) + AX := 0; AY := 0; AZ := 0; + tdSetTranslation( Trans ); + tdSetPerspective( 600*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, VtxCnt ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 1 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw objects *) + SortObjects; + for I:=0 to MAXCUB do with Cube[ZList[I]] do begin + for J:=0 to 5 do begin + K := Face[J].Texture; + mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width ); + end; + end; + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* If the frame rate seems low, try to remove this line *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO05.EXE b/16/x/modex/DEMO05.EXE new file mode 100755 index 00000000..21a7c207 Binary files /dev/null and b/16/x/modex/DEMO05.EXE differ diff --git a/16/x/modex/DEMO05.PAS b/16/x/modex/DEMO05.PAS new file mode 100755 index 00000000..819c5cf3 --- /dev/null +++ b/16/x/modex/DEMO05.PAS @@ -0,0 +1,131 @@ +(* + DEMO05 - A Gouraud-shaded rotating torus + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex, Threed; + +(* Define ALTPAL for alternate palette *) +{$define ALTPAL} + +const + MAXVTX1 = 15; RADIUS1 = 70; (* MAXVTX1+1 must be multiple of 4 *) + MAXVTX2 = 15; RADIUS2 = 30; + MAXVTX = (MAXVTX1+1)*(MAXVTX2+1)-1; + MAXFACE = MAXVTX; + Trans : TPoint = ( X:0; Y:0; Z:0 ); (* Object translation *) + Light : TPoint = ( X:0; Y:0; Z:-63*$10000 ); (* Light direction *) +type + TQuad = record + QVtx : array[ 0..3 ] of integer; + end; +var + Vtx, XVtx : array[ 0..MAXVTX ] of TPoint; (* Points *) + VVtx : array[ 0..MAXVTX ] of record X, Y: integer end; + Face : array[ 0..MAXFACE ] of TQuad; (* Polys *) + Culled : array[ 0..MAXFACE ] of integer; + GNrm,XGNrm: array[ 0..MAXVTX ] of TVector; (* Gouraud normals *) + VtxLight : array[ 0..MAXVTX ] of integer; (* Points brightness *) + Page : word; + +function GetVtx( I1, I2: integer ): integer; +begin + GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1); +end; + +procedure Init; +var + R, N, X, Y, Z: real; + I, J, K, V: integer; +begin + (* Build vertexes *) + for I:=0 to MAXVTX1 do begin + K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1); + R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) ); + for J:=0 to MAXVTX2 do begin + V := I*(MAXVTX2+1)+J; (* Index of current vertex *) + (* Compute coordinates of current vertex *) + X := R*Cos(2*J*Pi / (MAXVTX2+1)); (* Get coordinates *) + Y := R*Sin(2*J*Pi / (MAXVTX2+1)); + Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1)); + Vtx[V].X := Round( X )*$10000; (* Save coordinates *) + Vtx[V].Y := Round( Y )*$10000; + Vtx[V].Z := Round( Z )*$10000; + (* Compute direction of Gouraud normal thru current vertex *) + X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1)); + Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1)); + N := Sqrt( X*X + Y*Y + Z*Z ); (* Get vector length *) + GNrm[V].X := Trunc( X*$10000/N ); (* Save normal vector *) + GNrm[V].Y := Trunc( Y*$10000/N ); + GNrm[V].Z := Trunc( Z*$10000/N ); + end; + end; + (* Generate faces so that depth-sorting is not needed: there are still *) + (* some *very* little errors, but this is the best I could devise *) + J := 0; + K := 0; + for I:=0 to MAXFACE do with Face[I] do begin + QVtx[0] := GetVtx( J, K ); + QVtx[1] := GetVtx( J, K+1 ); + QVtx[2] := GetVtx( J+1, K+1 ); + QVtx[3] := GetVtx( J+1, K ); + Inc( K ); + if( K > MAXVTX2 ) then begin + K := 0; + Inc( J ); + end; + end; +{$ifndef ALTPAL} + for I:=0 to 63 do mxSetColor( I+64, 0, 0, I ); (* Blue palette *) +{$else} + for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *) + for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 ); +{$endif} +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetLight( Light ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, MAXVTX+1 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page ); + tdRotate( GNrm, XGNrm, MAXVTX+1 ); (* Rotate Gouraud normals *) + tdTransformLight( XGNrm, VtxLight, MAXVTX+1 ); + (* Backplane culling is not really needed here! *) + FillChar( Culled, SizeOf(Culled), 0 ); + tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 3 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw polygons *) + for I:=0 to MAXFACE do with Face[I] do + if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 ); + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* Uncomment this instruction if screen flickers *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO06.DAT b/16/x/modex/DEMO06.DAT new file mode 100755 index 00000000..1ac2c2bb Binary files /dev/null and b/16/x/modex/DEMO06.DAT differ diff --git a/16/x/modex/DEMO06.EXE b/16/x/modex/DEMO06.EXE new file mode 100755 index 00000000..f1308e8a Binary files /dev/null and b/16/x/modex/DEMO06.EXE differ diff --git a/16/x/modex/DEMO06.PAS b/16/x/modex/DEMO06.PAS new file mode 100755 index 00000000..f26af067 --- /dev/null +++ b/16/x/modex/DEMO06.PAS @@ -0,0 +1,135 @@ +(* + DEMO06 - Magnifying glass + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + R = 40; (* Lens radius *) + K : real = 1.8; (* Magnifying factor, less makes a stronger lens *) +type + TLine = array[ 0..319 ] of byte; + PLine = ^TLine; + TScreen = array[ 0..239 ] of PLine; +var + VScreen: TScreen; (* Virtual screen *) + BallX : array[ 0..R, 0..R ] of integer; + BallY : array[ 0..R, 0..R ] of integer; + Sprite : array[ -R..R, -R..R ] of byte; + Page : word; + +(* Returns "lens-view" coordinates of X,Y *) +procedure GetCoords( var X, Y: integer ); +var + LR, Z, SinA, SinB, TgB, Q: real; +begin + LR := Sqrt( X*X + Y*Y ); + if( LR = 0 ) then Exit; + if( LR < R ) then begin + Z := Sqrt( R*R - LR*LR ); + SinA := LR / R; + SinB := SinA / K; + TgB := SinB / Sqrt( 1-SinB*SinB ); + Q := LR - TgB*Z; + X := Round( X * ( Q/LR ) ); + Y := Round( Y * ( Q/LR ) ); + end; +end; + +procedure Init; +var + F : file; + Palette: array[ 0..767 ] of record R, G, B: byte; end; + X, Y, + X2, Y2 : integer; +begin + (* Load background image *) + Assign( F, 'demo06.dat' ); + Reset( F, 1 ); + BlockRead( F, Palette, 768 ); + mxSetPalette( @Palette, 0, 256 ); + for Y:=0 to 239 do begin + New( VScreen[Y] ); + BlockRead( F, VScreen[Y]^, 320 ); + mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE ); + end; + Close( F ); + (* Build lens *) + for X:=0 to R do begin + for Y:=0 to R do begin + X2 := X; + Y2 := Y; + GetCoords( X2, Y2 ); + BallX[X, Y] := X2; + BallY[X, Y] := Y2; + end; + end; +end; + +procedure PutLens( OX, OY: integer ); +var + X, Y: integer; +begin + for X:=0 to R do begin + for Y:=0 to R do begin + Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + end; + end; + (* Draw the sprite *) + mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE ); +end; + +function Delta: integer; +begin + Delta := Random(3)+2; +end; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*Delta; + end; +end; + +var + X, Y, DX, DY: integer; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; + X := R; + Y := R; + Randomize; + DX := Delta; + DY := Delta; + + (* Main loop *) + repeat + (* Update video *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + PutLens( X, Y ); + mxCircle( X, Page+Y, R, 0 ); + (* Update lens coordinates *) + Inc( X, DX ); + Check( X+R >= 319, X, DX, 319-R, -1 ); + Check( X <= R, X, DX, R, +1 ); + Inc( Y, DY ); + Check( Y+R >= 239, Y, DY, 239-R, -1 ); + Check( Y <= R, Y, DY, R, +1 ); + (* Flip pages: double buffering, avoid wait for display *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 0; end; + end; + mxWaitRetrace; (* Wait for hidden page to show *) + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/DEMO07.EXE b/16/x/modex/DEMO07.EXE new file mode 100755 index 00000000..8a401169 Binary files /dev/null and b/16/x/modex/DEMO07.EXE differ diff --git a/16/x/modex/DEMO07.PAS b/16/x/modex/DEMO07.PAS new file mode 100755 index 00000000..04fff790 --- /dev/null +++ b/16/x/modex/DEMO07.PAS @@ -0,0 +1,68 @@ +(* + DEMO07 - Hardware scrolling + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + (* Change this if scrolling seems jerky (this simple program does *) + (* not handle vertical retrace/display very well) *) + STEPS = 5; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*(Random(3)+2); + end; +end; + +var + I, X, Y, DX, DY: integer; +begin + (* Initialize library and graphics mode *) + mxInit; + mxSetMode( MX_320x200 ); + (* Set a 640x400 virtual screen *) + mxSetVirtualScreen( 640, 400 ); + mxSetClip( TRUE ); + + X := 0; + Y := 0; + DX := 1; + DY := 1; + + (* Main loop: draw lines, circles, points and rectangles in separate *) + (* 320x200 windows, while smoothly panning virtual screen *) + while( not KeyPressed ) do begin + (* Points *) + mxSetClipRegion( 0, 0, 320, 200 ); + for I:=1 to STEPS do + mxPutPixel( Random(320), Random(200), Random(16) ); + (* Lines *) + mxSetClipRegion( 0, 200, 320, 200 ); + for I:=1 to STEPS do + mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET ); + (* Circles *) + mxSetClipRegion( 320, 0, 320, 200 ); + for I:=1 to STEPS do + mxCircle( Random(320)+320, Random(200), Random(100), Random(16) ); + (* Boxes *) + mxSetClipRegion( 320, 200, 320, 200 ); + for I:=1 to STEPS do + mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET ); + (* Pan *) + Inc( X, DX ); + Check( X+320 >= 639, X, DX, 319, -1 ); + Check( X < 0, X, DX, 0, +1 ); + Inc( Y, DY ); + Check( Y+200 >= 399, Y, DY, 199, -1 ); + Check( Y < 0, Y, DY, 0, +1 ); + mxPan( X, Y ); + mxWaitRetrace; + end; + + (* Shutdown *) + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/MATH.INC b/16/x/modex/MATH.INC new file mode 100755 index 00000000..742af410 --- /dev/null +++ b/16/x/modex/MATH.INC @@ -0,0 +1,34 @@ +; +; MATH.INC - Include file for THREED.ASM +; + +; 3-dimensional point, coordinates in fixed format (16:16) +; +TPOINT STRUC + X DD ? + Y DD ? + Z DD ? +TPOINT ENDS + +; 2-dimensional point, coordinates in integer format +; +TIMAGEPOINT STRUC + IX DW ? + IY DW ? +TIMAGEPOINT ENDS + +; Fixed-point divide: EAX = EAX / arg +; +.xdiv MACRO arg + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv arg +ENDM + +; Fixed-point multiply: EAX = EAX * arg +; +.xmul MACRO arg + imul arg + shrd eax, edx, 16 +ENDM diff --git a/16/x/modex/PLASMA.PAS b/16/x/modex/PLASMA.PAS new file mode 100755 index 00000000..237e292a --- /dev/null +++ b/16/x/modex/PLASMA.PAS @@ -0,0 +1,103 @@ +unit Plasma; +interface + +const + PAL_RGB = 0; + PAL_CLOUDS = 1; + PAL_LANDSCAPE = 2; + +procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte ); +procedure MakePlasmaPalette( var Palette; What: word ); + +implementation uses Modex; + +procedure NewColor( XA, YA, X, Y, XB, YB: integer ); +var + Color: longint; +begin + Color := Abs( XA-XB )+Abs( YA-YB ); + Color := Random( Color shl 1 )-Color; + Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1; + if( Color < 1 ) then Color := 1; + if( Color > 192 ) then Color := 192; + if( mxGetPixel( X, Y ) = 0 ) then + mxPutPixel( X, Y, Lo(Color) ); +end; + +procedure Divide( X1, Y1, X2, Y2: integer ); +var + X, Y, Color: integer; +begin + if not( (X2-X1<2)and(Y2-Y1<2) ) then begin + X := (X1+X2) shr 1; + Y := (Y1+Y2) shr 1; + NewColor( X1, Y1, X, Y1, X2, Y1 ); + NewColor( X2, Y1, X2, Y, X2, Y2 ); + NewColor( X1, Y2, X, Y2, X2, Y2 ); + NewColor( X1, Y1, X1, Y, X1, Y2 ); + Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+ + mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2; + mxPutPixel( X, Y, Color ); + Divide( X1, Y1, X, Y ); + Divide( X, Y1, X2, Y ); + Divide( X, Y, X2, Y2 ); + Divide( X1, Y, X, Y2 ); + end; +end; + +procedure MakePlasma; +begin + Dec( W ); + Dec( H ); + mxPutPixel( X, Y, C1 ); + mxPutPixel( X, Y+H, C2 ); + mxPutPixel( X+W, Y+H, C3 ); + mxPutPixel( X+W, Y, C4 ); + Divide( X, Y, X+W, Y+H ); +end; + +procedure MakePlasmaPalette; +type + TPal = array[ byte ] of record R, G, B: byte end; +var + I: word; +begin + FillChar( TPal(Palette)[1], 192*3, 0 ); + case What of + PAL_CLOUDS: + for I:=1 to 192 do begin + TPal(Palette)[I].R := Abs( I-96 )*63 div 96; + TPal(Palette)[I].G := Abs( I-96 )*63 div 96; + TPal(Palette)[I].B := 63; + end; + PAL_LANDSCAPE: + begin + for I:=0 to 31 do begin + TPal(Palette)[I+1].R := I; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := I + I shr 1+15; + end; + for I:=32 to 63 do begin + TPal(Palette)[I+1].R := 0; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := 0; + end; + for I:=64 to 191 do begin + TPal(Palette)[I+1].R := (I-64) div 3 + 15; + TPal(Palette)[I+1].G := (I-64) div 3 + 15; + TPal(Palette)[I+1].B := (I-64) div 3 + 15; + end; + end; + else + for I:=1 to 64 do begin + TPal(Palette)[I].G := I-1; + TPal(Palette)[I].B := 64-I; + TPal(Palette)[I+64].R := I-1; + TPal(Palette)[I+64].G := 64-I; + TPal(Palette)[I+128].B := I-1; + TPal(Palette)[I+128].R := 64-I; + end; + end; +end; + +end. \ No newline at end of file diff --git a/16/x/modex/QIX2.EXE b/16/x/modex/QIX2.EXE new file mode 100755 index 00000000..a10d7db5 Binary files /dev/null and b/16/x/modex/QIX2.EXE differ diff --git a/16/x/modex/QIX2.PAS b/16/x/modex/QIX2.PAS new file mode 100755 index 00000000..d1b59791 --- /dev/null +++ b/16/x/modex/QIX2.PAS @@ -0,0 +1,210 @@ +{$E-,N+} +uses Crt, Modex; + +const + DEFVERT = 12; (* Vertex count *) + DEFREPL = 3; (* Repetition count *) + DEFQIXS = 2; (* Qixs *) + FADESPEED = 48; +type + TPoint = record + X, Y : integer; + end; + TRGB = record + R, G, B: byte; + end; + TQix = record + Color: integer; + Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint; + Delta: array[ 0..DEFVERT-1 ] of TPoint; + end; +var + Page : integer; + MaxX, + MaxY : word; + Qix : array[ 0..DEFQIXS-1 ] of TQix; + Pal : array[ byte ] of TRGB; + +type + TReal = double; + TRPoint = record + X, Y: TReal; + end; + TMatrix = array[ 0..3, 0..3 ] of TReal; +var + M: TMatrix; + G: array[ 0..DEFVERT-1 ] of TRPoint; + C: array[ 0..DEFVERT-1 ] of TRPoint; + +procedure BumpPal( Idx, DR, DG, DB, Steps: integer ); +var + I: integer; +begin + for I:=1 to Steps do begin + Pal[Idx+1].R := Pal[Idx].R + DR; + Pal[Idx+1].G := Pal[Idx].G + DG; + Pal[Idx+1].B := Pal[Idx].B + DB; + Inc( Idx ); + end; +end; + +procedure InitPalette; +begin + with Pal[0] do begin R:=0; G:=0; B:=0; end; + with Pal[1] do begin R:=0; G:=0; B:=62; end; + BumpPal( 1, 0, 2, -2, 31 ); + BumpPal( 32, 2, -2, 0, 31 ); + BumpPal( 63, -2, 2, 2, 31 ); + BumpPal( 94, 2, 0, -2, 31 ); + BumpPal( 125, -2, -2, 2, 31 ); +end; + +procedure Init( var Qix: TQix; Color: integer ); +var + I: integer; +begin + FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 ); + for I:=0 to DEFVERT-1 do begin + Qix.Vert[I, DEFREPL-1].X := Random( MaxX ); + Qix.Vert[I, DEFREPL-1].Y := Random( MaxY ); + Qix.Delta[I].X := Random(5)+1; + Qix.Delta[I].Y := Random(5)+1; + end; + Qix.Color := Color; + + (* Initialize matrix (Catmull-Rom) *) + M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2; + M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2; + M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0; + M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0; +end; + +procedure mxBezier( var Qix: TQix; I0, Idx, N: integer ); +var + I, J: integer; + T, T2, T3: TReal; + X0, Y0, X, Y: TReal; + Delta: TReal; +begin + (* Compute coefficients *) + for I:=0 to 3 do begin + C[I].X := 0; + for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X; + C[I].Y := 0; + for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y; + end; + X0 := C[3].X; + Y0 := C[3].Y; + Delta := 1 / N; + T := 0; + for I:=1 to N do begin + T := T + Delta; + T2 := T*T; + T3 := T*T2; + X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X; + Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y; + mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET ); + X0 := X; + Y0 := Y; + end; +end; + +procedure Plot( var Qix: TQix; Idx: integer ); +var + I, J: integer; +begin + for I:=0 to DEFVERT-1 do begin + mxBezier( Qix, I, Idx, 12 ); + end; +end; + +procedure Update( var Qix: TQix; Idx: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Inc( Vert[I,Idx].X, Delta[I].X ); + if( Vert[I,Idx].X < 0 ) then begin + Vert[I,Idx].X := 0; + Delta[I].X := Random( 5 )+1; + end; + if( Vert[I,Idx].X > MaxX ) then begin + Vert[I,Idx].X := MaxX; + Delta[I].X := -Random( 5 )-1; + end; + Inc( Vert[I,Idx].Y, Delta[I].Y ); + if( Vert[I,Idx].Y < 0 ) then begin + Vert[I,Idx].Y := 0; + Delta[I].Y := Random( 5 )+1; + end; + if( Vert[I,Idx].Y > MaxY ) then begin + Vert[I,Idx].Y := MaxY; + Delta[I].Y := -Random( 5 )-1; + end; + end; +end; + +procedure Copy( var Qix: TQix; Dest, Src: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Vert[I,Dest].X := Vert[I,Src].X; + Vert[I,Dest].Y := Vert[I,Src].Y; + end; +end; + +procedure AnimateQix; +var + Q, Idx, I, J, P, Count: integer; +begin + Count := 0; + P := DEFREPL-1; + I := 0; + J := 1; + repeat + mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 ); + mxSetClip( TRUE ); + mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET ); + for Q:=0 to DEFQIXS-1 do begin + Copy( Qix[Q], I, P ); + Update( Qix[Q], I ); + for Idx:=0 to DEFREPL-1 do begin + Plot( Qix[Q], Idx ); + end; + end; + I := (I+1) mod DEFREPL; + J := (J+1) mod DEFREPL; + P := (P+1) mod DEFREPL; + Inc( Count ); + mxStartLine( Page ); + if( Count >= FADESPEED ) then begin + for Q:=0 to DEFQIXS-1 do begin + Inc( Qix[Q].Color ); + if( Qix[Q].Color > 156 ) then + Qix[Q].Color := 1; + end; + Count := 0; + end; + Page := 240-Page; + until( KeyPressed ); +end; + +var + I: integer; +begin + Randomize; + mxInit; + mxSetMode( MX_320x240 ); + mxGetScreenSize( MaxX, MaxY ); + for I:=0 to DEFQIXS-1 do + Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 ); + InitPalette; + mxSetPalette( @Pal, 0, 157 ); + Page := 240; + Dec( MaxX ); + Dec( MaxY ); + AnimateQix; + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x/modex/README.TXT b/16/x/modex/README.TXT new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/x/modex/README.TXT @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/x/modex/SINCOS.INC b/16/x/modex/SINCOS.INC new file mode 100755 index 00000000..6986eeeb --- /dev/null +++ b/16/x/modex/SINCOS.INC @@ -0,0 +1,518 @@ +; +; SINCOS.INC - Sin/cos tables for THREED.ASM +; + +tblSin LABEL DWORD + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 +tblCos LABEL DWORD + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 diff --git a/16/x/modex/THREED.ASM b/16/x/modex/THREED.ASM new file mode 100755 index 00000000..5ecd3ba3 --- /dev/null +++ b/16/x/modex/THREED.ASM @@ -0,0 +1,872 @@ +COMMENT / + Fixed-point math functions and 3D transforms + Copyright (c) 1993,94 by Alessandro Scotti +/ +WARN PRO +P386 +JUMPS +LOCALS + +INCLUDE MATH.INC + +PUBLIC tdFixedMul +PUBLIC tdGetNormal +PUBLIC tdRotate +PUBLIC tdGetSurfaceLight +PUBLIC tdSetLight +PUBLIC tdSetRotation +PUBLIC tdSetTranslation +PUBLIC tdTransform +PUBLIC tdTransformToImage +PUBLIC tdTransformLight +PUBLIC tdBackPlaneCull +PUBLIC tdSetPerspective + +;----------------------------------------------------------- +; +; Data segment +; +MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' + ASSUME ds:MATH_DATA + +INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table + +XRotation TPOINT <> ; 3x3 rotation matrix +YRotation TPOINT <> +ZRotation TPOINT <> + +Translation TPOINT <> ; Translation vector + +Light TPOINT <> ; Light vector +AmbientLight DW 00 ; Ambient light + +XScale DD 10000h ; Scaling factor for X coordinate +YScale DD 10000h ; Scaling factor for Y coordinate +PerspectiveDistance DD 20000000h + +MATH_DATA ENDS + +;----------------------------------------------------------- +; +; Code segment +; +MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING + +tdSetPerspective PROC PASCAL FAR + ARG Perspective:DWORD, \ + ScaleX:DWORD, \ + ScaleY:DWORD + USES ds + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov eax, [Perspective] + mov [PerspectiveDistance], eax + mov eax, [ScaleX] + mov [XScale], eax + mov eax, [ScaleY] + mov [YScale], eax + + ret +tdSetPerspective ENDP + + +;----------------------------------------------------------- +; +; Sets the rotation matrix. +; +; Input: +; RX = X-axis rotation angle +; RY = X-axis rotation angle +; RZ = X-axis rotation angle +; Output: +; none +; +tdSetRotation PROC PASCAL FAR + ARG RX:WORD, \ + RY:WORD, \ + RZ:WORD + USES ds, si, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov bx, [RZ] + mov si, [RY] + mov di, [RX] + shl bx, 2 + shl si, 2 + shl di, 2 + + push ebp ; We use EBP as a scratch register + +; Set X rotation + mov eax, tblCos[bx] + imul tblCos[si] + mov [XRotation.X], edx + + mov eax, tblSin[bx] + imul tblCos[si] + mov [XRotation.Y], edx + + mov eax, tblSin[si] + sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 + mov [XRotation.Z], eax + +; Set Y rotation + mov eax, tblCos[bx] + imul tblSin[si] ; EDX:EAX = fixed 16:48 + shrd eax, edx, 24 ; EAX = fixed 8:24 + imul tblSin[di] ; EDX:EAX = fixed 16:48 + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblCos[di] + add eax, ebp + adc edx, ecx ; EDX:EAX = fixed 16:48 + neg edx + mov [YRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblSin[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblCos[di] + sub eax, ebp + sbb edx, ecx + mov [YRotation.Y], edx + + mov eax, tblCos[si] + imul tblSin[di] + mov [YRotation.Z], edx + +; Set Z rotation + mov eax, tblCos[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblSin[di] + sub eax, ebp + sbb edx, ecx + mov [ZRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblSin[di] + add eax, ebp + add edx, ecx + neg edx + mov [ZRotation.Y], edx + + mov eax, tblCos[si] + imul tblCos[di] + mov [ZRotation.Z], edx + + pop ebp ; Restore EBP + + ret +tdSetRotation ENDP + +;----------------------------------------------------------- +; +; Sets the translation vector. +; +; Input: +; TV = pointer to translation vector +; Output: +; none +; +tdSetTranslation PROC PASCAL FAR + ARG TV:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [TV] + mov eax, es:[di].X + mov [Translation.X], eax + mov eax, es:[di].Y + mov [Translation.Y], eax + mov eax, es:[di].Z + mov [Translation.Z], eax + + ret +tdSetTranslation ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdTransform PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + LOCAL Adjust:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + + ALIGN DWORD +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + mov ebx, eax + shrd eax, edx, 16 + add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) + mov es:[di].Z, eax +; Get perspective factor + mov ebx, [PerspectiveDistance] + sub eax, ebx + neg eax ; EAX = PD - Z + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv ebx ; EAX = fixed 16:16 result + mov [Adjust], eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.X] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.Y] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdTransform ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT into an array of TIMAGEPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TIMAGEPOINT +; Count = number of entries to transform +; DeltaX = translation distance for the X coordinate +; DeltaY = translation distance for the Y coordinate +; Output: +; the maximum Z value +; +tdTransformToImage PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD + LOCAL Adjust:DWORD, \ + Max:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + mov [Max], 80000000h + +@@Loop: +; Check max Z + mov eax, fs:[si].Z + cmp eax, [Max] + jle @@1 + mov [Max], eax +@@1: + +; Transform X coordinate + mov ax, WORD PTR fs:[si].X[2] + add ax, [DeltaX] + mov es:[di].IX, ax + +; Transform Y coordinate + mov ax, WORD PTR fs:[si].Y[2] + add ax, [DeltaY] + mov es:[di].IY, ax + + add si, SIZE TPOINT + add di, SIZE TIMAGEPOINT + dec [Count] + jnz @@Loop + + mov eax, [Max] + shld edx, eax, 16 + ret +tdTransformToImage ENDP + +;----------------------------------------------------------- +; +; Sets the light source. +; +; Input: +; Light = pointer to light vector +; Output: +; none +; +tdSetLight PROC PASCAL FAR + ARG L:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [L] + mov eax, es:[di].X + mov [Light.X], eax + mov eax, es:[di].Y + mov [Light.Y], eax + mov eax, es:[di].Z + mov [Light.Z], eax + + ret +tdSetLight ENDP + +;----------------------------------------------------------- +; +; Computes light intensity for an array of surfaces. +; +; Input: +; Normals = pointer to an array of surface normals +; Lights = pointer to an array of integer to be filled with +; light intensity +; Count = number of elements to transform +; Output: +; none +; +tdTransformLight PROC PASCAL FAR + ARG Normals:DWORD, \ + Lights:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov fs, ax + ASSUME fs:MATH_DATA + + lds si, [Normals] + les di, [Lights] + ASSUME ds:NOTHING + +; Intensity is given by the dot product between the Light vector and +; the surface normal +@@Loop: + mov eax, ds:[si].Z + imul [Light.Z] + mov ebx, eax + mov ecx, edx + mov eax, ds:[si].Y + imul [Light.Y] + add ebx, eax + adc ecx, edx + mov eax, ds:[si].X + imul [Light.X] + add eax, ebx + adc edx, ecx ; EDX:EAX = fixed 32:32 intensity + add dx, [AmbientLight] + test dx, dx + jg @@1 + xor dx, dx ; Return 0 for no light +@@1: + mov es:[di], dx + inc di + inc di + add si, SIZE TPOINT + dec [Count] + jnz @@Loop + + ASSUME fs:NOTHING + ret +tdTransformLight ENDP + +;----------------------------------------------------------- +; +; Returns the light value given the normal to a surface. +; +; Input: +; Normal = pointer to TPOINT surface normal vector +; Output: +; AX = light intensity (>=0) +; Notes: +; the normal is rotated according to the current setting. +; +tdGetSurfaceLight PROC PASCAL FAR + ARG Normal:DWORD + USES ds, esi, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [Normal] + +; Transform Z coordinate + mov eax, es:[di].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.Z] + shrd eax, edx, 16 + mov esi, eax + +; Transform X coordinate + mov eax, es:[di].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add esi, eax + +; Transform Y coordinate + mov eax, es:[di].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add eax, esi + shr eax, 16 + +; Add ambient light + add ax, [AmbientLight] + test ax, ax + jge @@Exit + xor ax, ax + +@@Exit: + ret +tdGetSurfaceLight ENDP + +;----------------------------------------------------------- +; +; Rotates an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdRotate PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Z, eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdRotate ENDP + +tdFixedMul PROC PASCAL FAR + ARG F1:DWORD, \ + F2:DWORD + + mov eax, [F1] + imul [F2] + shr eax, 16 + + ret +tdFixedMul ENDP + +;----------------------------------------------------------- +; +; Returns in EAX the square root of EDX:EAX. +; +subSqrt PROC NEAR + push esi + push edi + + add eax, eax + adc edx, 0 + mov eax, edx ; Just discard the low bits + + mov esi, eax + xor edi, edi + shld edi, esi, 16 + shl esi, 16 +@@Loop: + mov ebx, eax + mul eax + add eax, esi + adc edx, edi + shrd eax, edx, 1 + shr edx, 1 + div ebx + cmp eax, ebx + jne @@Loop + +; Adjust EAX + shl eax, 8 + + pop edi + pop esi + ret +subSqrt ENDP + +;----------------------------------------------------------- +; +; Finds the unitary normal to a given surface. +; +; Input: +; Dest = pointer to TPOINT (vector) result +; P1, P2, P3 = pointer to TPOINT points on surface +; Output: +; none +; Notes: +; the normal is given by the cross-product between (P3-P1) and +; (P2-P1), so its orientation depends on the parameters order. +; +tdGetNormal PROC PASCAL FAR + ARG Dest:DWORD, \ + P1:DWORD, \ + P2:DWORD, \ + P3:DWORD + LOCAL V1:TPOINT, \ + V2:TPOINT, \ + N:TPOINT + USES ds, si, es, di + +; Get vector V1 + lds si, [P1] + les di, [P3] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V1.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V1.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V1.Z], eax + +; Get vector V2 + les di, [P2] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V2.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V2.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V2.Z], eax + +; Get normal vector (V1 x V2) + mov eax, [V1.Z] + imul [V2.Y] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Y] + imul [V2.Z] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.X], eax + + mov eax, [V1.X] + imul [V2.Z] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Z] + imul [V2.X] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Y], eax + + mov eax, [V1.Y] + imul [V2.X] + mov ebx, eax + mov ecx, edx + mov eax, [V1.X] + imul [V2.Y] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Z], eax + +; Get normal length + mov eax, [N.X] + imul eax + mov ebx, eax + mov ecx, edx + mov eax, [N.Y] + imul eax + add ebx, eax + adc ecx, edx + mov eax, [N.Z] + imul eax + add eax, ebx + adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z + call subSqrt ; EAX = normal length + mov ebx, eax + +; Adjust vector and save it + les di, [Dest] + mov eax, [N.X] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].X, eax + mov eax, [N.Y] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Y, eax + mov eax, [N.Z] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Z, eax + + ret +tdGetNormal ENDP + +TPOLY STRUC + Vtx DW 4 DUP(?) +TPOLY ENDS + +;----------------------------------------------------------- +; +; Performs surface removal on an array of polygons. +; +; Input: +; Poly = pointer to an array of TPOLY +; Vertex = pointer to an array of TPOINT +; Dest = pointer to an array of integer +; Count = number of polygons to check +; Step = size of TPOLY structure +; Output: +; if the n-th polygon is invisible the n-th entry of the +; Dest array is set to -1, other entries are not modified +; (so it's possible to use the Light array for Dest, because +; the light intensity is always >= 0) +; +tdBackPlaneCull PROC PASCAL FAR + ARG Step:WORD, \ + Poly:DWORD, \ + Vertex:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + ASSUME ds:NOTHING + + mov ds, WORD PTR Vertex[2] + les di, [Poly] + mov fs, WORD PTR Dest[2] + +@@Loop: + mov ax, es:[di].Vtx[2] ; Index of 2nd vertex + shl ax, 2 + mov bx, ax + shl ax, 1 + add bx, ax ; BX = index*SIZE TPOINT + add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex + mov ax, es:[di].Vtx[4] ; Index of 3rd vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex + mov ecx, ds:[si].X + sub ecx, ds:[bx].X ; ECX = V3.X-V2.X + mov edx, ds:[si].Y + sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y + mov ax, es:[di].Vtx[0] ; Index of 1st vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 1st vertex + mov eax, ds:[si].X + sub eax, ds:[bx].X ; EAX = V1.X-V2.X + mov esi, ds:[si].Y + sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y + imul edx + mov ebx, eax + xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) + mov eax, esi + imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) + sub eax, ebx + sbb edx, ecx + jl @@Next ; Polygon is visible + mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry + mov WORD PTR fs:[bx], -1 ; Remove polygon +@@Next: + add WORD PTR [Dest], 2 ; Next entry for dest + add di, [Step] ; Next polygon + dec [Count] + jnz @@Loop + + ret +tdBackPlaneCull ENDP + +MATH_TEXT ENDS +END diff --git a/16/x/modex/THREED.H b/16/x/modex/THREED.H new file mode 100755 index 00000000..b993ef86 --- /dev/null +++ b/16/x/modex/THREED.H @@ -0,0 +1,32 @@ +typedef struct { + long x, y, z; +} TVECTOR; + +#define PVECTOR TVECTOR far * + +#define TPOINT TVECTOR +#define PPOINT PVECTOR + +#define VPTR void far * + +#ifdef __cplusplus +extern "C" { +#endif + +long far pascal tdFixedMul( long, long ); +int far pascal tdGetSurfaceLight( PPOINT ); +long far pascal tdTransformToImage( VPTR, VPTR, short, short, short ); + +void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short ); +void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT ); +void far pascal tdRotate( VPTR, VPTR, short ); +void far pascal tdSetLight( PVECTOR ); +void far pascal tdSetRotation( short, short, short ); +void far pascal tdSetTranslation( PVECTOR ); +void far pascal tdSetPerspective( long, long, long ); +void far pascal tdTransform( VPTR, VPTR, short ); +void far pascal tdTransformLight( VPTR, VPTR, short ); + +#ifdef __cplusplus +} +#endif diff --git a/16/x/modex/THREED.PAS b/16/x/modex/THREED.PAS new file mode 100755 index 00000000..8b712c9d --- /dev/null +++ b/16/x/modex/THREED.PAS @@ -0,0 +1,40 @@ +unit ThreeD; +interface + +type + TVector = record + X, Y, Z : longint; + end; + TPoint = TVector; + +function tdFixedMul( F1, F2: longint ): longint; +function tdGetSurfaceLight( var Normal: TPoint ): integer; +function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint; + +procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word ); +procedure tdGetNormal( var Dest, P1, P2, P3: TVector ); +procedure tdRotate( var Source, Dest; Count: word ); +procedure tdSetLight( var Light: TVector ); +procedure tdSetRotation( RX, RY, RZ: word ); +procedure tdSetTranslation( var TV: TVector ); +procedure tdSetPerspective( PD, XF, YF: longint ); +procedure tdTransform( var Source, Dest; Count: word ); +procedure tdTransformLight( var Source, Dest; Count: word ); + +implementation + +function tdGetSurfaceLight; external; +procedure tdSetRotation( RX, RY, RZ: word ); external; +procedure tdGetNormal; external; +procedure tdSetTranslation( var TV: TVector ); external; +procedure tdTransform( var Source, Dest; Count: word ); external; +procedure tdRotate; external; +function tdTransformToImage; external; +procedure tdSetLight( var Light: TVector ); external; +procedure tdSetPerspective; external; +procedure tdTransformLight; external; +function tdFixedMul( F1, F2: longint ): longint; external; +procedure tdBackPlaneCull; external; +{$L THREED} + +end. diff --git a/16/x/mxbb.asm b/16/x/mxbb.asm new file mode 100755 index 00000000..ac6668ce --- /dev/null +++ b/16/x/mxbb.asm @@ -0,0 +1,278 @@ +;----------------------------------------------------------- +; +; MXBB.ASM - Bit block transfer +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxBitBlt + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN subHorizontalLineInfo : NEAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves a block of video memory. +; +; Input: +; SX, SY = source coordinates +; Width = source width +; Height = source height +; DX, DY = destination coordinates +; Output: +; none +; +; Note: overlapping regions are not allowed. +; +mxBitBlt PROC FAR + ARG DestY:WORD, \ + DestX:WORD, \ + Height:WORD, \ + Width:WORD, \ + SY:WORD, \ + SX:WORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + SourceOffset:WORD, \ + DestOffset:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + WritePlane:BYTE, \ + LeftMask:BYTE, \ + RightMask:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + +; Exit now if null width + cmp [Width], 0 + je @@Exit + +; Calls the proper procedure to handle transfer + mov ax, [SX] + and al, 03h ; AL = source plane + mov dx, [DestX] + and dl, 03h ; DL = destination plane + mov bx, OFFSET subPlaneBlt + cmp al, dl ; Same source and destination plane? + jne @@BitBlt ; No, use slow procedure + mov bx, OFFSET subMoveBlt +@@BitBlt: + call bx + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; Uses write mode 1 for maximum speed. Only works if source +; and destination are plane-aligned. +; +subMoveBlt PROC NEAR +; Get horizontal line info and address of destination + mov bx, [DestX] + mov ax, [DestY] + mov cx, [Width] + call subHorizontalLineInfo + mov [LeftMask], al + mov [RightMask], ah + mov [Width], cx + +; Setup segments + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + +; Get address of source pixel + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + .shr si, 2 + add si, ax + +; Set write mode 1 + mov dx, GDC + mov ax, 4105h + out dx, ax + cld + +; Move left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] + .push si, di +@@L1: + movsb + add si, ax + add di, ax + dec cx + jnz @@L1 + .pop si, di + inc si + inc di + +; Move center block +@@C0: + mov bx, [Width] + test bx, bx + jz @@R0 + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov ax, [mx_BytesPerLine] + sub ax, bx + mov dx, [Height] + .push si, di +@@C1: + mov cx, bx ; CX = image width + rep movsb ; Cannot use "movsw" here! + add si, ax ; Next scan line + add di, ax ; Next scan line + dec dx ; All lines processed? + jnz @@C1 ; No, continue + .pop si, di + add si, bx + add di, bx + +; Move right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] +@@R1: + movsb + add si, ax + add di, ax + dec cx + jnz @@R1 + +@@Done: + mov dx, GDC + mov ax, 4005h + out dx, ax ; Restore write mode 0 + +@@Exit: + ret +subMoveBlt ENDP + +;----------------------------------------------------------- +; Moves one plane at a time. +; +subPlaneBlt PROC NEAR +; Compute extra bytes and width count for each plane + mov cx, [Width] + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Get pixel addresses + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + shr si, 1 + shr si, 1 + add si, ax ; DS:SI points to source + mov [SourceOffset], si + mov ax, [DestY] + mul [mx_BytesPerLine] + mov di, [DestX] + shr di, 1 + shr di, 1 + add di, ax ; ES:DI points to destination + mov [DestOffset], di + +; Adjust plane for output to VGA registers + mov ax, [SX] + and al, 03h + mov [ReadPlane], al + mov cx, [DestX] + and cl, 03h + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Ready to move now + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 + je @@Done + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov ax, [mx_BytesPerLine] + sub ax, ss:[bx] ; AX = extra bytes per line +@@Loop: + mov cx, ss:[bx] + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb + add si, ax + add di, ax + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + and [ReadPlane], 03h ; Should be faster on 386 using + jnz @@ReadPlaneOk ; BTR and ADC... + inc [SourceOffset] +@@ReadPlaneOk: + rol [WritePlane], 1 + adc [DestOffset], 0 + mov si, [SourceOffset] + mov di, [DestOffset] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Done: + ret +subPlaneBlt ENDP + +mxBitBlt ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxcc.asm b/16/x/mxcc.asm new file mode 100755 index 00000000..4f78adb9 --- /dev/null +++ b/16/x/mxcc.asm @@ -0,0 +1,644 @@ +;----------------------------------------------------------- +; +; MXCC.ASM - Fast clip line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC xsubClipLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblGroups LABEL WORD + DW 10, tbl00 + DW 10, tbl10 + DW 9, tbl20 + DW -1, 0 + DW 10, tbl40 + DW 10, tbl50 + DW 9, tbl60 + DW -1, 0 + DW 6, tbl80 + DW 6, tbl90 + DW 5, tblA0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 +tbl00 DW cc00, cc01, cc02, ccFF, cc04, cc05, cc06, ccFF, cc08, cc09, cc0A +tbl10 DW cc10, ccFF, cc12, ccFF, cc14, ccFF, cc16, ccFF, cc18, ccFF, cc1A +tbl20 DW cc20, cc21, ccFF, ccFF, cc24, cc25, ccFF, ccFF, cc28, cc29 +tbl40 DW cc40, cc41, cc42, ccFF, ccFF, ccFF, ccFF, ccFF, cc48, cc49, cc4A +tbl50 DW cc50, ccFF, cc52, ccFF, ccFF, ccFF, ccFF, ccFF, cc58, ccFF, cc5A +tbl60 DW cc60, cc61, ccFF, ccFF, ccFF, ccFF, ccFF, ccFF, cc68, cc69 +tbl80 DW cc80, cc81, cc82, ccFF, cc84, cc85, cc86 +tbl90 DW cc90, ccFF, cc92, ccFF, cc94, ccFF, cc96 +tblA0 DW ccA0, ccA1, ccFF, ccFF, ccA4, ccA5 + +ccTT: clc + ret +ccFF: stc + ret + +; Group 00 ------------------------------------------------- +; +cc00: + clc + ret +cc01: + jmp ClipQLeft +cc02: + jmp ClipQRight +cc04: + jmp ClipQTop +cc05: + call ClipQLeft + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc06: + call ClipQRight + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc08: + jmp ClipQBottom +cc09: + call ClipQLeft + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom +cc0A: + call ClipQRight + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom + +; Group 10 ------------------------------------------------- +; +cc10FF: + stc + ret +cc10TT: + clc + ret +cc10: + jmp ClipPLeft +cc12: + call ClipPLeft + jmp ClipQRight +cc14: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + jmp ClipQTop +cc16: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + call ClipQTop + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight +cc18: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + jmp ClipQBottom +cc1A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + call ClipQBottom + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight + +; Group 20 ------------------------------------------------- +; +cc20TT: + clc + ret +cc20FF: + stc + ret +cc20: + jmp ClipPRight +cc21: + call ClipPRight + jmp ClipQLeft +cc24: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + jmp ClipQTop +cc25: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + call ClipQTop + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft +cc28: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + jmp ClipQBottom +cc29: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + call ClipQBottom + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft + +; Group 40 ------------------------------------------------- +; +cc40TT: + clc + ret +cc40FF: + stc + ret +cc40: + jmp ClipPTop +cc41: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc40TT + jmp ClipQTop +cc42: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + jmp ClipQRight +cc48: + call ClipPTop + jmp ClipQBottom +cc49: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom +cc4A: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + call ClipQRight + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom + + +; Group 50 ------------------------------------------------- +; +cc50TT: + clc + ret +cc50FF: + stc + ret +cc50: + call ClipPLeft + cmp bx, [mx_ClipY1] + jge cc50TT + jmp ClipPTop +cc52: + call ClipQRight + cmp si, [mx_ClipY1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc58: + call ClipQBottom + cmp cx, [mx_ClipX1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc5A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc50FF + call ClipQRight + cmp bx, [mx_ClipY1] + jl cc50FF + cmp si, [mx_ClipY2] + jle cc50TT + jmp ClipQBottom + +; Group 60 ------------------------------------------------- +; +cc60TT: + clc + ret +cc60FF: + stc + ret +cc60: + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc61: + call ClipQLeft + cmp si, [mx_ClipY2] + jl cc60FF + call ClipPTop + cmp di, [mx_ClipX2] + jle cc60TT + jmp ClipPRight +cc68: + call ClipQBottom + cmp cx, [mx_ClipX2] + jg cc60FF + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc69: + call ClipQLeft + cmp si, [mx_ClipY1] + jl cc60FF + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc60FF + cmp si, [mx_ClipY2] + jle cc69_1 + call ClipQBottom +cc69_1: + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop + +; Group 80 ------------------------------------------------- +; +cc80TT: + clc + ret +cc80FF: + stc + ret +cc80: + jmp ClipPBottom +cc81: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + jmp ClipQLeft +cc82: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + jmp ClipQRight +cc84: + call ClipPBottom + jmp ClipQTop +cc85: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc80FF + jmp ClipQTop +cc86: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + call ClipQRight + cmp si, [mx_ClipY1] + jge cc80TT + jmp ClipQTop + +; Group 90 ------------------------------------------------- +; +cc90TT: + clc + ret +cc90FF: + stc + ret +cc90: + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc92: + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + call ClipPBottom + cmp di, [mx_ClipX1] + jge cc90TT + jmp ClipPLeft +cc94: + call ClipQTop + cmp cx, [mx_ClipX1] + jl cc90FF + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc96: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc90FF + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + cmp bx, [mx_ClipY2] + jle cc96_1 + call ClipPBottom +cc96_1: + cmp si, [mx_ClipY1] + jge cc90TT + jmp ClipQTop + +; Group A0 ------------------------------------------------- +; +ccA0TT: + clc + ret +ccA0FF: + stc + ret +ccA0: + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA1: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPBottom + cmp di, [mx_ClipX2] + jle ccA0TT + jmp ClipPRight +ccA4: + call ClipQTop + cmp cx, [mx_ClipX2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA5: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY1] + jl ccA0FF + cmp si, [mx_ClipY1] + jge ccA5_1 + call ClipQTop +ccA5_1: + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom + +; Y1 = (Y2-Y1)*(mx_ClipX1-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX1-DI)/(CX-DI)+BX +; X1 = mx_ClipX1 +ClipPLeft: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX1] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX1] + clc + ret + +; Y1 = (Y2-Y1)*(mx_ClipX2-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX2-DI)/(CX-DI)+BX +; X1 = mx_ClipX2 +ClipPRight: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX2] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY2-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY2-BX)/(SI-BX)+DI +; Y1 = mx_ClipY2 +ClipPBottom: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY2] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY1-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY1-BX)/(SI-BX)+DI +; Y1 = mx_ClipY1 +ClipPTop: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY1] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX1-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX1-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQLeft: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX1] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX2-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX2-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQRight: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX2] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY2-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY2-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQBottom: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY2] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY1-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY1-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQTop: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY1] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY1] + clc + ret + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses the Sobkow-Pospisil-Yang (SPY) algorithm: this was +; supposed to be twice as fast as Cohen-Sutherland, but my +; tests show only a very small increase in speed and a noticeable +; increase of the program size! Maybe this is caused by the +; slow speed of VGA cards, so probably a better test should +; be performed with lines drawn in RAM. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +xsubClipLine PROC NEAR + push bp + xor si, si ; SPY code + + cmp dx, [mx_ClipY2] + jle @@1 + or si, 08h + jmp @@2 +@@1: + cmp dx, [mx_ClipY1] + jge @@2 + or si, 04h +@@2: + + cmp cx, [mx_ClipX2] + jle @@3 + or si, 02h + jmp @@4 +@@3: + cmp cx, [mx_ClipX1] + jge @@4 + or si, 01h +@@4: + + cmp bx, [mx_ClipY2] + jle @@5 + or si, 80h + jmp @@6 +@@5: + cmp bx, [mx_ClipY1] + jge @@6 + or si, 40h +@@6: + + cmp ax, [mx_ClipX2] + jle @@7 + or si, 20h + jmp @@8 +@@7: + cmp ax, [mx_ClipX1] + jge @@8 + or si, 10h +@@8: + + mov di, si + and di, 000Fh ; Index of procedure + and si, 00F0h + .shr si, 2 ; Index of group (times 4) + cmp di, cs:tblGroups[si] ; Is index within range? + jg @@Exit ; No, line is full clipped + mov si, cs:tblGroups[si+2] ; Get offset of group table + shl di, 1 ; We must index word elements + add si, di ; Make full offset + mov di, ax ; Move X1 to DI and free AX + mov si, cs:[si] ; Get subroutine address + xchg dx, si ; Move Y2 to SI and free DX + call dx ; Call the proper subroutine + mov ax, di ; Restore AX to X1 + mov dx, si ; Restore DX to Y2 + pop bp + ret + +@@Exit: + pop bp + stc + ret +xsubClipLine ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxcg.asm b/16/x/mxcg.asm new file mode 100755 index 00000000..42163d7a --- /dev/null +++ b/16/x/mxcg.asm @@ -0,0 +1,69 @@ +;----------------------------------------------------------- +; +; MXCG.ASM - Color to gray conversion +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxColorToGray + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Converts RGB colors to gray shades. +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gray) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxColorToGray PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit + lds si, [SPal] + les di, [DPal] + cld +; We use the standard formula +; gray=(red*30 + green*59 + blue*11)/100 +; in the equivalent form +; gray=(red*77 + green*151 + blue*28)/256 +; which doesn't need the last divide. + mov bx, 77 SHL 8 + 151 +@@Loop: + lodsb ; Red + mul bh + mov dx, ax + lodsb ; Green + mul bl + add dx, ax + lodsb ; Blue + mov ah, 28 + mul ah + add ax, dx + mov al, ah + stosw ; Save new RGB + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxColorToGray ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxcl.asm b/16/x/mxcl.asm new file mode 100755 index 00000000..aaa0bac3 --- /dev/null +++ b/16/x/mxcl.asm @@ -0,0 +1,151 @@ +;----------------------------------------------------------- +; +; MXCL.ASM - Bresenham circle +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxCircle + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws a circle using the Bresenham algorithm. +; +; Input: +; XC, YC = center coordinates +; Radius = circle radius +; Color = circle color +; Output: +; none +; Note: +; computes only points in the first octant, all other +; points are obtained by symmetry. +; +mxCircle PROC FAR + ARG Color:BYTE:2, \ + Radius:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL Delta:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + xor si, si ; X + mov di, [Radius] ; Y + mov ax, 3 + sub ax, di + sub ax, di + mov [Delta], ax ; Delta = 3-R*2 + + mov ds, [mx_VideoSegment] + +@@Loop: + cmp si, di ; + jg @@Done ; Exit when X > Y +; Draw points + mov ax, si + mov bx, di + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + call @@subPutPixel + mov ax, si + mov bx, di + neg bx + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + neg bx + call @@subPutPixel + mov ax, di + mov bx, si + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + call @@subPutPixel + mov ax, di + mov bx, si + neg bx + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + neg bx + call @@subPutPixel +; Moves coordinates to next point + mov ax, [Delta] + test ax, ax + jl @@Next + mov ax, di + .shl ax, 2 + sub ax, 4 + sub [Delta], ax + dec di +@@Next: + mov ax, si + .shl ax, 2 + add ax, 6 + add [Delta], ax + inc si + jmp @@Loop + +@@Done: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;--------------------------------------- +; Put pixel function. +; Input: +; BX = X coordinate (relative to center) +; AX = Y coordinate (relative to center) +; DS = video segment +@@subPutPixel: + add bx, [XC] ; Get absolute coordinates + add ax, [YC] + + cmp bx, [mx_ClipX1] ; Clip pixel + jl @@subExit + cmp bx, [mx_ClipX2] + jg @@subExit + cmp ax, [mx_ClipY1] + jl @@subExit + cmp ax, [mx_ClipY2] + jg @@subExit + + mul [mx_BytesPerLine] ; Get pixel offset + mov cx, bx ; Save X coordinate + .shr bx, 2 + add bx, ax ; DS:BX = pixel offset + + and cl, 3 ; Set write plane + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[bx], al + +@@subExit: + retn +mxCircle ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxcr.asm b/16/x/mxcr.asm new file mode 100755 index 00000000..ca1fa7bb --- /dev/null +++ b/16/x/mxcr.asm @@ -0,0 +1,380 @@ +;----------------------------------------------------------- +; +; MXCR.ASM - Clip functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetSysClipRegion +PUBLIC mxGetClipRegion +PUBLIC mxSetClipRegion +PUBLIC mxSetClip +PUBLIC mxGetClip + +PUBLIC subClipBox +PUBLIC subClipImage + +PUBLIC mx_ClipX1 +PUBLIC mx_ClipY1 +PUBLIC mx_ClipX2 +PUBLIC mx_ClipY2 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD + +mx_ClipX1 DW ? ; Clip coordinates +mx_ClipY1 DW ? +mx_ClipX2 DW ? +mx_ClipY2 DW ? + +mx_SysClipX1 DW ? ; System clip coordinates +mx_SysClipY1 DW ? ; (active when mx_ClipStatus is FALSE) +mx_SysClipX2 DW ? +mx_SysClipY2 DW ? + +mx_UserClipX1 DW ? ; User clip coordinates +mx_UserClipY1 DW ? ; (active when mx_ClipStatus is TRUE) +mx_UserClipX2 DW ? +mx_UserClipY2 DW ? + +mx_ClipStatus DB ? + +;----------------------------------------------------------- +; +; Toggles clipping between user and system regions. +; +; Input: +; ClipStatus = TRUE (FALSE) to enable (disable) clipping +; Output: +; AX = old clip status +; +mxSetClip PROC FAR + ARG ClipStatus:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [mx_UserClipX1] + mov bx, [mx_UserClipY1] + mov cx, [mx_UserClipX2] + mov dx, [mx_UserClipY2] + cmp [ClipStatus], TRUE + je @@Done + mov ax, [mx_SysClipX1] + mov bx, [mx_SysClipY1] + mov cx, [mx_SysClipX2] + mov dx, [mx_SysClipY2] +@@Done: + mov [mx_ClipX1], ax + mov [mx_ClipY1], bx + mov [mx_ClipX2], cx + mov [mx_ClipY2], dx + + mov al, [ClipStatus] + xchg al, [mx_ClipStatus] + xor ah, ah + + .pop ds + .leave ARG_SIZE +mxSetClip ENDP + +;----------------------------------------------------------- +; +; Returns the current clipping status. +; +; Input: +; none +; Output: +; TRUE (FALSE) if clipping enabled (disabled) +; +mxGetClip PROC FAR + ASSUME ds:NOTHING + mov al, [mx_ClipStatus] + xor ah, ah + ret +mxGetClip ENDP + +;----------------------------------------------------------- +; +; Sets the system clip region and disables user clipping. +; +; Input: +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; old clip status. +; +mxSetSysClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + xor ax, ax ; Sys clip region always starts at (0,0) + mov [mx_SysClipX1], ax + mov [mx_SysClipY1], ax + mov ax, [Width] + dec ax + mov [mx_SysClipX2], ax + mov ax, [Height] + dec ax + mov [mx_SysClipY2], ax + + IF USE286 EQ TRUE + push FALSE + ELSE + mov ax, FALSE + push ax + ENDIF + call mxSetClip + + .pop ds + .leave ARG_SIZE +mxSetSysClipRegion ENDP + +;----------------------------------------------------------- +; +; Sets the clip region. +; +; Input: +; X, Y = coordinates of top left corner of clip region +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; none (no checking on parameters) +; +mxSetClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [X] + mov [mx_UserClipX1], ax + mov ax, [Y] + mov [mx_UserClipY1], ax + mov ax, [Width] + add ax, [X] + dec ax + mov [mx_UserClipX2], ax + mov ax, [Height] + add ax, [Y] + dec ax + mov [mx_UserClipY2], ax + + mov al, [mx_ClipStatus] + cmp al, TRUE + jne @@Exit + push ax + call mxSetClip + +@@Exit: + xor ax, ax + .pop ds + .leave ARG_SIZE +mxSetClipRegion ENDP + +;----------------------------------------------------------- +; +; Returns the current user clip region. +; +; Input: +; X, Y = pointers to integer coordinates of top left corner +; Width = pointer to word width of clip region +; Height = pointer to word height of clip region +; Output: +; AX = current clip status +; +mxGetClipRegion PROC FAR + ARG Height:DWORD, \ + Width:DWORD, \ + Y:DWORD, \ + X:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + mov ax, [mx_UserClipX1] + les di, [X] + mov es:[di], ax + mov ax, [mx_UserClipY1] + les di, [Y] + mov es:[di], ax + + mov ax, [mx_UserClipX2] + sub ax, [mx_UserClipX1] + inc ax + les di, [Width] + mov es:[di], ax + mov ax, [mx_UserClipY2] + sub ax, [mx_UserClipY1] + inc ax + les di, [Height] + mov es:[di], ax + + mov al, [mx_ClipStatus] + xor ah, ah + .pop es, di + .leave ARG_SIZE +mxGetClipRegion ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; This function assumes that a "raw" image has to be clipped, +; so it returns in SI the number of "raw" bytes to skip if +; X, Y were clipped. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; SI = number of bytes to skip before copying a buffer +; DI destroyed +; +subClipImage PROC NEAR + ASSUME ds:NOTHING + xor si, si + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, di + mov di, dx ; Save box height into DI + mul cx ; DX:AX = number of bytes to skip + mov si, ax + mov dx, di ; Restore box height + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax + jge @@DoneHeight ; None, continue + add dx, di ; Clip lines +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + add si, di ; Update skip count + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx + jge @@DoneWidth ; None, exit + add cx, di ; New box width +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipImage ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; DI destroyed +; +subClipBox PROC NEAR + ASSUME ds:NOTHING + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax ; Clipped some point? + jge @@DoneHeight ; No, continue + add dx, di ; Clip lines (DI is negative) +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx ; Clipped some point? + jge @@DoneWidth ; No, exit + add cx, di ; New box width (DI is negative) +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipBox ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxel.asm b/16/x/mxel.asm new file mode 100755 index 00000000..2c9dda2a --- /dev/null +++ b/16/x/mxel.asm @@ -0,0 +1,167 @@ +;----------------------------------------------------------- +; +; MXEL.ASM - Mid-point ellipse +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxEllipse + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws an ellipse using the mid-point algorithm. +; +; Input: +; XC, YC = center coordinates +; A = horizontal radius +; B = vertical radius +; Color = ellipse color +; Output: +; none +; Note: +; computes only points in the first quadrant, all other +; points are obtained by symmetry. +; +mxEllipse PROC FAR + ARG Color:BYTE:2, \ + B:WORD, \ + A:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL A2:DWORD, \ + B2:DWORD, \ + CC:DWORD, \ + DD:DWORD, \ + X:DWORD, \ + Y:DWORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + .chk386 mxEllipse, @@Exit + +; Initialize variables + xor eax, eax + mov [X], ax ; X = 0 + mov ax, [A] + mul eax ; EAX = A*A + mov [DD], eax ; DD = A*A + shl eax, 1 + mov [CC], eax ; CC = 2*A*A + shl eax, 1 + mov [A2], eax ; A2 = 4*A*A + movzx edx, [B] + mov [Y], edx + mul edx ; EAX = 4*A*A*B + sub [DD], eax ; DD = A*A - 4*A*A*B + movzx eax, [B] + mul eax ; EAX = B*B + shl eax, 2 ; EAX = 4*B*B + mov [B2], eax ; B2 = 4*B*B + add [CC], eax ; CC = 2*A*A + 4*B*B + add [D1], eax ; DD = A*A - 4*A*A*B + 4*B*B + +; Draw initial points + call subPlot4 + +; First loop +@@Loop1: + mov eax, [X] ; Check slope + mul [B2] + mov ecx, eax + mov eax, [Y] + mul [A2] + sub eax, ecx + sub eax, [CC] ; EAX = Y*A2 - X*B2 - CC + jle @@Done1 ; Crossed critical point, jump to next loop + + mov ecx, [DD] ; Get error + test ecx, ecx ; Positive? + jl @@Draw1 ; No, use default step + + mov eax, 1 + sub eax, [Y] + mul [A2] + shl eax, 1 + add ecx, eax ; Bump error + dec WORD PTR [Y] ; Decrement Y coordinate + +@@Draw1: + mov eax, [X] + shl eax, 1 + add eax, 3 + mul [B2] + add ecx, eax ; Bump error + mov [DD], ecx ; Save error + inc WORD PTR [X] ; Increment X coordinate + + call subPlot4 ; Draw points + jmp @@Loop1 +@@Done1: + +; Initialize variables + shr [B2], 2 + mov eax, [X] + mul eax + add [X] + shl eax, 2 + inc eax + mul [B2] + mov [DD], eax + mov eax, [Y] + mul eax + add [Y] + dec eax + add [Y] + sub eax, [B2] + add [DD], eax + shl [B2], 3 + inc WORD PTR [X] + +; Second loop +@@Loop2: + cmp WORD PTR [Y], 0 + ja @@Done2 + + mov ecx, [DD] + test ecx, ecx + jge @@Draw2 + + mov eax, [X] + inc eax + mul [B2] + add ecx, eax + inc WORD PTR [X] + +@@Draw2: + mov eax, [Y] + shl eax, 1 + sub eax, 3 + neg eax + imul [A2] + add ecx, eax + dec WORD PTR [Y] + + call subPlot4 + jmp @@Loop2 +@@Done2: + +@@Exit: + xor ax, ax + .leave ARG_SIZE +mxEllipse ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxfb.asm b/16/x/mxfb.asm new file mode 100755 index 00000000..41ea5deb --- /dev/null +++ b/16/x/mxfb.asm @@ -0,0 +1,194 @@ +;----------------------------------------------------------- +; +; MXFB.ASM - Fill box function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillBox + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN subClipBox : NEAR +EXTRN subHorizontalLineInfo : NEAR + +;----------------------------------------------------------- +; +; Raster op functions. Raster op is limited to OP_MOVE, +; OP_AND, OP_OR and OP_XOR. The VGA hardware is used to +; perform the selected logical functions on up to four +; pixel at a time. +; +subRepFill PROC NEAR + mov ah, al + shr cx, 1 + rep stosw + rcl cx, 1 + rep stosb + ret +subRepFill ENDP +; +subFill PROC NEAR +@@Loop: + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subFill ENDP +; +subRepMove PROC NEAR + mov si, di +@@Loop: + mov ah, ds:[si] ; Dummy read to latch the data + mov ds:[si], al + inc si + loop @@Loop + ret +subRepMove ENDP +; +subMove PROC NEAR +@@Loop: + mov ah, ds:[bx] ; Dummy read to latch the data + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subMove ENDP + +;----------------------------------------------------------- +; +; Fills a rectangle with a specified color. +; +; Input: +; X, Y = X, Y coordinates of rectangle +; Width = width of rectangle +; Height = height of rectangle +; Color = fill color +; Op = raster operator +; Output: +; none +; +; Note: raster op is limited to OP_MOVE, OP_AND, OP_OR and OP_XOR. +; +mxFillBox PROC FAR + ARG Op:WORD, \ + Color:BYTE:2, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL LeftMask:BYTE, \ + RightMask:BYTE, \ + FillFunction:WORD, \ + RepFillFunction:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Clip rectangle + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipBox + jc @@Exit ; Full clipped + + mov [Height], dx ; Save clipped height + call subHorizontalLineInfo ; Get additional info, init DI + mov [Width], cx + mov [LeftMask], al + mov [RightMask], ah + +; Initialize segments + mov ax, [mx_VideoSegment] + mov es, ax ; ES:DI points to pixel + mov ds, ax + cld ; Clear direction flag + +; Select fill functions + mov [FillFunction], OFFSET subFill + mov [RepFillFunction], OFFSET subRepFill + mov ax, [Op] ; Get raster op + cmp al, OP_XOR + ja @@1 ; Assume it's a fill + cmp al, OP_MOVE + je @@1 + .shl al, 3 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set GDC logical function + mov [FillFunction], OFFSET subMove + mov [RepFillFunction], OFFSET subRepMove +@@1: + +; Fill left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 ; Nothing to do, go to center block + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + inc di ; Update starting video offset + +; Fill center block +@@C0: + mov cx, [Width] + jcxz @@R0 ; Nothing to do, go to right block + mov dx, TS + mov ax, 0F02h + out dx, ax ; Write to all planes + mov al, [Color] + mov bx, di + mov dx, [Height] + push di ; Save pixel address +@@C1: + mov di, bx ; Update video offset + call [RepFillFunction] ; Fill current scan line + mov cx, [Width] ; Restore byte count + add bx, [mx_BytesPerLine] ; Bump to next scan line + dec dx ; Done all lines? + jnz @@C1 ; No, continue + pop di ; Restore pixel address + add di, [Width] ; Go to right block + +; Fill right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done ; Nothing to do, exit + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + +; Restore VGA registers +@@Done: + mov dx, GDC + mov ax, 0003h + out dx, ax ; Set logical function to "move" + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillBox ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxfp.asm b/16/x/mxfp.asm new file mode 100755 index 00000000..8eea25be --- /dev/null +++ b/16/x/mxfp.asm @@ -0,0 +1,326 @@ +;----------------------------------------------------------- +; +; MXFP.ASM - Fade palette function +; Copyright (c) 1992-1994 ARTIS s.r.l. +; Author: Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxFadePalette + +MAXCOLOR EQU 256 +FADE_IN EQU 0 +FADE_OUT EQU 1 + +; The actual speed of fading depends on the number of passes (FADE_SPEED) and +; the delay between two consecutive passes (FADE_DELAY). Below are the +; default values, used when no parameters are specified. +; +FADE_DELAY EQU 1 ; Vert. retraces between video updates +FADE_SPEED EQU 48 ; Speed of effect (max 127) + +; Bit field record for fade commands +; +FADE_COMMAND RECORD fpDELAY:8,fpSPEED:7,fpDIRECTION:1 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'Copyright (c) 1992-1994 ARTIS s.r.l. All rights reserved.' + +;----------------------------------------------------------- +; +; Fades a VGA palette. +; +; Input: +; Buffer = pointer to source/destination palette +; Command = fading direction and optional parameters +; Start = index of first color to fade +; Count = number of color to fade +; Red = destination red +; Green = destination green +; Blue = destination blue +; Output: +; none +; Notes: +; - about 1.5 Kbytes of stack space are needed for internal buffers; +; - the Command argument usually is 0 to fade in and 1 to fade out, +; however additional parameters may be specified. To set the effect +; speed, i.e. the number of iterations needed to completely fade a +; palette, shift the value one bit left and "or" it with the +; direction bit (range is 0..127). To set the delay between two +; consecutive passes, shift it eight bits left (range is 0..255). +; +mxFadePalette PROC FAR + ARG bBlue:WORD, \ + bGreen:WORD, \ + bRed:WORD, \ + wCount:WORD, \ + wStartIdx:WORD, \ + wCommand:WORD, \ + vfpPalette:DWORD = ARG_SIZE + LOCAL bSPalette:BYTE:MAXCOLOR*3, \ + bDPalette:BYTE:MAXCOLOR*3, \ + bLoopIndex:BYTE, \ + bLoopStep:BYTE, \ + bLoopCount:BYTE, \ + wDelay:WORD, \ + wSpeed:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push si, di, ds, es ; Save registers +; +; Check parameters and setup variables +; +@@GetDelay: + mov [wDelay], FADE_DELAY ; Set default delay + mov ax, [wCommand] ; Get command word + and ax, MASK fpDELAY ; Mask delay command + jz @@GetSpeed ; No command, get speed + IF USE286 EQ TRUE + shr ax, fpDELAY + ELSE + mov cl, fpDELAY ; Get size of delay field + shr ax, cl ; Right justify the field + ENDIF + mov [wDelay], ax ; Set new delay + +@@GetSpeed: + mov ax, [wCommand] ; Get command + and ax, MASK fpSPEED ; Mask speed + IF USE286 EQ TRUE + shr ax, fpSPEED + ELSE + mov cl, fpSPEED ; Get size of speed field + shr ax, cl ; Right justify the field + ENDIF + or ax, ax ; Any speed specified? + jnz @@SetVariables ; Yes, set variables + mov ax, FADE_SPEED ; Set default speed + +@@SetVariables: + mov [wSpeed], ax ; Set speed + inc ax ; Number of iterations + mov [bLoopCount], al ; Set loop count + mov [bLoopStep], 1 ; Assume we're fading in + mov [bLoopIndex], 0 +; +; Check bounds for bad values +; + mov ax, [wStartIdx] ; Get first index + cmp ax, MAXCOLOR ; Is in the valid range? + jae @@Exit ; No, exit + add ax, [wCount] ; Get last index + cmp ax, MAXCOLOR ; Is in the valid range? + jbe @@BoundsOk ; Yes, continue + mov ax, MAXCOLOR + sub ax, [wStartIdx] + mov [wCount], ax ; Set count to maximum value + or ax, ax + jz @@Exit ; Nothing to do, exit +@@BoundsOk: +; +; Copy the source palette in a local array: if we fade in it's ready to +; use, otherwise we'll overwrite it later +; + mov cx, [wCount] + mov ax, cx + shl ax, 1 + add cx, ax ; CX = wCount * 3 + mov ax, ss + mov es, ax + lea di, [bSPalette] ; ES:DI points to local palette + mov ax, [wStartIdx] + mov si, ax + shl ax, 1 + add ax, si + lds si, [vfpPalette] ; DS:SI points to user palette + add si, ax ; Skip unused entries + cld + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb +; +; Check direction +; + test [wCommand], MASK fpDIRECTION ; Are we fading in? + jz @@Main ; Yes, ok to continue + mov ax, [wSpeed] ; Get speed + mov [bLoopIndex], al ; Exchange first and last index + mov [bLoopStep], -1 ; Move backward + mov ax, ss ; Overwrite our copy of + mov ds, ax ; user palette with the + mov es, ax ; current active palette + lea di, [bSPalette] + mov ax, [wStartIdx] + mov cx, [wCount] + call ReadPalette ; Read current palette +; +; Prepare variables and registers for fading +; +@@Main: + mov bh, BYTE PTR [bRed] ; Destination red + and bh, 00111111b ; Be sure it's a valid VGA value + mov bl, BYTE PTR [bGreen] ; Destination green + and bl, 00111111b ; Be sure it's a valid VGA value + mov dh, BYTE PTR [bBlue] ; Destination blue + and dh, 00111111b ; Be sure it's a valid VGA value + mov dl, [bLoopIndex] ; Loop index + mov ax, ss ; All tables are stored + mov ds, ax ; in the stack segment, + mov es, ax ; set DS and ES +; +; Main loop +; +@@Loop: + mov ax, [wCount] ; Store count in AX + mov cx, [wSpeed] ; Set maximum speed in CX + lea si, [bSPalette] ; DS:SI points to source palette + lea di, [bDPalette] ; ES:DI points to dest. palette + call RecalcPalette ; Build a faded palette + + .push bx, dx ; Save registers we need + lea si, [bDPalette] ; DS:SI points to palette + mov ax, [wStartIdx] ; First index to write + mov bx, [wCount] ; Total entries to write + mov cx, [wDelay] ; Fade delay between updates + call WritePalette ; Write palette + .pop bx, dx ; Restore BX and DX + + add dl, [bLoopStep] ; Change fade intensity + dec [bLoopCount] ; Done? + jnz @@Loop ; No, loop again + +@@Exit: + .pop si, di, ds, es ; Restore registers + .leave ARG_SIZE +mxFadePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Calculates a partially faded palette. +; +; Input: +; AX = number of entries in palette +; CX = maximum fade intensity (same as fade speed) +; DS:SI = pointer to source palette +; ES:DI = pointer to destination palette +; BH = destination red +; BL = destination green +; DH = destination blue +; DL = relative intensity of destination palette +; Note: +; it's important that a new palette can be calculated in less +; than 1/70th of second. Fading to any RGB value requires use +; of "imul" instructions: "idiv" may be replaced with faster +; "sar", but only when the number of passes is a power of two, +; thus reducing the range of selectable speeds. +; In both cases an extimate of CPU cycles required by this +; procedure shows that it's too slow to run on a 4.77 Mhz 8086 +; CPU and a 256 color palette, so we keep "idiv" and hope +; the target machine to be at least a 6 Mhz 80286 (that's not +; asking too much...). +; +RecalcPalette PROC NEAR + cld + push bp ; Save BP + mov bp, ax ; Copy counter in BP +@@Loop: + lodsb ; Red: read value + sub al, bh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bh ; Add destination value... + stosb ; ...and store it + lodsb ; Green: read value + sub al, bl ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bl ; Add destination value... + stosb ; ...and store it + lodsb ; Blue: read value + sub al, dh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, dh ; Add destination value... + stosb ; ...and store it + dec bp + jnz @@Loop + pop bp ; Restore BP + ret +RecalcPalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Writes a 256 color palette. +; +; Input: +; AX = index of first color to write +; BX = number of colors to write (each color is an RGB triplet) +; CX = number of vertical retraces to wait before writing to DACs +; DS:SI = pointer to first entry of palette +; +WritePalette PROC NEAR + ASSUME ds:NOTHING + mov ah, al ; Save index + mov dx, 03DAh ; Input status register +@@Delay1: + in al, dx + test al, 08h + jnz @@Delay1 ; Wait for display mode +@@Delay2: + in al, dx + test al, 08h + jz @@Delay2 ; Wait for vertical retrace mode + loop @@Delay1 ; Repeat CX times +@@Write: + mov cx, bx ; Get number of colors + mov dx, 03C8h ; PEL write address register + mov al, ah ; Restore index + out dx, al ; Select index of first color + inc dx ; PEL data register + cld ; Move forward + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + ret +WritePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Reads the current palette. +; +; Input: +; AX = index of first color to read +; CX = number of colors +; ES:DI = pointer to destination buffer +; +ReadPalette PROC NEAR + mov dx, 03C7h + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop + ret +ReadPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxgc.asm b/16/x/mxgc.asm new file mode 100755 index 00000000..85edf7a6 --- /dev/null +++ b/16/x/mxgc.asm @@ -0,0 +1,54 @@ +;----------------------------------------------------------- +; +; MXGC.ASM - Get color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the selected DAC register. +; +; Input: +; Index = color index (0-255) +; R, G, B = byte pointers to red, green and blue +; Output: +; none +; +mxGetColor PROC FAR + ARG B:DWORD, \ + G:DWORD, \ + R:DWORD, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + + lds si, [R] + in al, dx + mov ds:[si], al + lds si, [G] + in al, dx + mov ds:[si], al + lds si, [B] + in al, dx + mov ds:[si], al + + .pop ds, si + .leave ARG_SIZE +mxGetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxgi.asm b/16/x/mxgi.asm new file mode 100755 index 00000000..7037d411 --- /dev/null +++ b/16/x/mxgi.asm @@ -0,0 +1,132 @@ +;----------------------------------------------------------- +; +; MXGI.ASM - Get image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGetImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies an image from screen to memory. +; +; Input: +; Image = pointer to buffer for image +; X, Y = coordinates of image on screen +; Width = width of image in pixels +; Height = height of image in pixels +; Output: +; none +; +mxGetImage PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + Count:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov si, bx + shr si, 1 + shr si, 1 + add si, ax + mov [PixelOffset], si + mov ds, [mx_VideoSegment] ; DS:SI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov di, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[di], bx + shr al, 1 + adc bx, 0 + dec di + dec di + jge @@PatchLoop + +; Get image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov es, WORD PTR Image[2] ; ES:DI will point to image + mov ah, [ReadPlane] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov di, WORD PTR Image[0] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov si, [PixelOffset] ; DS:SI points to video memory +@@Loop: + .push si, di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move +@@MoveLoop: + movsb + add di, 3 + dec cx + jnz @@MoveLoop + .pop si, di + add di, [Width] ; Go to next image line + add si, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc ah + test ah, 04h ; Plane wraparound? + jz @@PlaneOk ; No + inc [PixelOffset] ; Yes, bump video pointer + and ah, 03h +@@PlaneOk: + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGetImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxgm.asm b/16/x/mxgm.asm new file mode 100755 index 00000000..a67476a0 --- /dev/null +++ b/16/x/mxgm.asm @@ -0,0 +1,63 @@ +;----------------------------------------------------------- +; +; MXGM.ASM - Gamma correction +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGammaCorrect + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +mx_tblGamma LABEL BYTE + DB 00, 10, 14, 17, 19, 21, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34 + DB 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46 + DB 47, 48, 48, 49, 49, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55 + DB 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63 + +;----------------------------------------------------------- +; +; Correct palette colors (gamma is 2.3). +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gamma corrected) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxGammaCorrect PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit ; Exit now if nothing to do + lds si, [SPal] + les di, [DPal] + mov bx, OFFSET mx_tblGamma ; Setup BX for XLAT instruction + cld + mov ax, cx ; AX = Count + add cx, cx ; CX = Count*2 + add cx, ax ; CX = Count*3 +@@Loop: + lodsb + xlat mx_tblGamma + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxGammaCorrect ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxgp.asm b/16/x/mxgp.asm new file mode 100755 index 00000000..6c143173 --- /dev/null +++ b/16/x/mxgp.asm @@ -0,0 +1,56 @@ +;----------------------------------------------------------- +; +; MXGP.ASM - Get palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to get +; Count = number of color to get +; Output: +; none +; +mxGetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + les di, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop ; Loop until done + + .pop es, di + .leave ARG_SIZE +mxGetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxgv.asm b/16/x/mxgv.asm new file mode 100755 index 00000000..2a54b1d0 --- /dev/null +++ b/16/x/mxgv.asm @@ -0,0 +1,25 @@ +;----------------------------------------------------------- +; +; MXGV.ASM - Get version function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetVersion + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the library version. +; +mxGetVersion PROC FAR + mov ax, MXVERSION + ret +mxGetVersion ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxhl.asm b/16/x/mxhl.asm new file mode 100755 index 00000000..049a0566 --- /dev/null +++ b/16/x/mxhl.asm @@ -0,0 +1,76 @@ +;----------------------------------------------------------- +; +; MXHL.ASM - Horizontal line mask utility +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC subHorizontalLineInfo + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +tblLeftSize DW 00h, 03h, 02h, 01h +tblLeftMask DB 00h, 0Eh, 0Ch, 08h +tblRightMask DB 00h, 01h, 03h, 07h +tblPatchMask DB 02h, 06h + +;----------------------------------------------------------- +; +; Prepares register for fast horizontal line drawing. +; +; Input: +; BX, AX = X, Y address of left pixel +; CX = line width +; Output: +; DI = left pixel offset in video memory +; AL = left block write plane mask (0 = none) +; AH = right block write plane mask (0 = none) +; CX = center block width in 4-pixel blocks +; +subHorizontalLineInfo PROC NEAR + ASSUME ds:NOTHING + + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax ; Offset of left pixel + + and bx, 03h + mov al, tblLeftMask[bx] + shl bx, 1 + sub cx, tblLeftSize[bx] + jge @@1 ; Ok to continue + +; Special case: start and end in the middle of a 4-pixel block. +; There are only three cases: +; Pixels Left mask CX CX+2 Patch mask Result +; 1) ..o. ..xx -1 1 .xx. ..x. +; 2) .oo. .xxx -1 1 .xx. .xx. +; 3) .o.. .xxx -2 0 .x.. .x.. +; All other cases are automatically handled with the standard masks. + mov bx, cx + inc bx + inc bx + and al, tblPatchMask[bx] ; Combine masks + xor ah, ah ; No right block + xor cx, cx ; No center block + jmp @@Exit + +@@1: + mov bx, cx + and bx, 03h + mov ah, tblRightMask[bx] + shr cx, 2 + +@@Exit: + ret +subHorizontalLineInfo ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxit.asm b/16/x/mxit.asm new file mode 100755 index 00000000..c0d9cedd --- /dev/null +++ b/16/x/mxit.asm @@ -0,0 +1,98 @@ +;----------------------------------------------------------- +; +; MXIT.ASM - Initialization/termination functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxInit +PUBLIC mxTerm + +PUBLIC mx_VideoSegment +PUBLIC mx_CodeSegment + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'MODEX library - Copyright (c) 1992-1994 Alessandro Scotti' + +mx_VideoSegment DW 0A000h +mx_CodeSegment DW SEG MX_TEXT + +;----------------------------------------------------------- +; +; Initialization. +; +; Input: +; none +; Output: +; AX = 0 on success +; +mxInit PROC FAR + LOCAL Result:WORD, \ + VideoSeg:WORD, \ + CStoDSalias:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov [Result], -1 ; Assume an error + mov [VideoSeg], 0A000h ; Real mode video segment + mov [CStoDSalias], cs ; Real mode data alias for CS + +; Check if running in protected mode under DPMI + mov ax, 1686h + int 2Fh + or ax, ax + jnz @@1 ; DPMI not found, continue in real mode + +; Get a data alias for CS + mov ax, 000Ah ; DMPI: create data alias + mov bx, cs + int 31h + jc @@Exit ; Exit if service failed + mov [CStoDSalias], ax ; Save data alias for CS +; Get a protected-mode selector for the video segment + mov ax, 0002h + mov bx, 0A000h ; Real mode segment of video + int 31h ; DPMI: get segment selector + jc @@Exit ; Exit if service failed + mov [VideoSeg], ax ; Save protected mode video selector + +; Initialize variables +@@1: + mov ds, [CStoDSalias] + ASSUME ds:MX_TEXT + mov [mx_CodeSegment], ds + mov ax, [VideoSeg] + mov [mx_VideoSegment], ax + +; Don't bother with VGA check for now... + + mov [Result], 0 + +@@Exit: + mov ax, [Result] + .pop ds, si, es, di + .leave +mxInit ENDP + +;----------------------------------------------------------- +; +; Termination. +; +; Input: +; none +; Output: +; always 0. +; +mxTerm PROC FAR + ASSUME ds:NOTHING + xor ax, ax + ret +mxTerm ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxll.asm b/16/x/mxll.asm new file mode 100755 index 00000000..34fec043 --- /dev/null +++ b/16/x/mxll.asm @@ -0,0 +1,82 @@ +;----------------------------------------------------------- +; +; MXLL.ASM - Load latches +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxLoadLatches + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD + +;----------------------------------------------------------- +; +; Loads the specified value into the VGA latches. +; +; Input: +; BL = value to load into latches +; Output: +; none +; Changes: +; bit mask register to FFh; +; function select register to "move"; +; write mode to 00h. +; Note: +; this is for internal use only. +; +mxLoadLatches PROC NEAR + ASSUME ds:NOTHING + + .push ds, si + mov dx, GDC + mov ax, 0FF08h + out dx, ax ; Set bit mask to FFh + mov ax, 0003h + out dx, ax ; Set function to "move" + mov ax, 0005h + out dx, ax ; Set write mode + mov ax, [mx_VideoSegment] + mov ds, ax + mov si, 0FFFFh + mov bh, 8 ; BH = write plane mask + mov cx, 3 ; CX = count = read plane +; Saves old values and force BL into latches +@@SetLoop: + mov dx, GDC + mov al, 04h + mov ah, cl + out dx, ax ; Select read plane + mov dx, TS + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + mov al, ds:[si] + push ax + mov ds:[si], bl + mov al, ds:[di] ; Force value into latch + shr bh, 1 ; Next write plane + loop @@SetLoop +; Restore previous values + mov cx, 3 + mov bh, 8 + mov dx, TS +@@ResetLoop: + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + pop ax + mov ds:[si], al + shr bh, 1 ; Next write plane + loop @@ResetLoop +; Exit + .pop ds, si + ret +mxLoadLatches ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxln.asm b/16/x/mxln.asm new file mode 100755 index 00000000..fbc4ab94 --- /dev/null +++ b/16/x/mxln.asm @@ -0,0 +1,414 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Line function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblDrawFunc LABEL WORD + DW subWidthMove + DW subHeightMove + DW subWidthOp + DW subHeightOp + +;----------------------------------------------------------- +; +; Draws a line from (X1,Y1) to (X2,Y2) using the Bresenham +; algorithm. +; +; Input: +; X1, Y1 = start point +; X2, Y2 = end point +; Color = line color +; Op = raster operator +; Output: +; none +; +; Note: the end point (X2,Y2) *IS* drawed. I don't like this very much +; but clipping is much simpler. +; +mxLine PROC FAR + ARG Op:WORD, \ + Color:WORD, \ + Y2:WORD, \ + X2:WORD, \ + Y1:WORD, \ + X1:WORD = ARG_SIZE + LOCAL Width:WORD, \ + Height:WORD, \ + ErrorAdd:WORD, \ + ErrorSub:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD, \ + P1:BYTE, \ + P2:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + ASSUME ds:NOTHING + + mov ax, [X1] + mov bx, [Y1] + mov cx, [X2] + mov dx, [Y2] + call subClipLine + jc @@Exit ; Line is full clipped + +; Get width + mov si, cx + xchg ax, si ; SI = X1, AX = X2 + sub ax, si + jge @@1 +; Swap points, we want X1 < X2 + xchg si, cx ; Swap X1 and X2 + xchg bx, dx ; Swap Y1 and Y2 + neg ax +@@1: + mov [Width], ax + +; Get height + mov cx, [mx_BytesPerLine] ; We don't need X2 anymore + mov ax, dx + sub ax, bx + jge @@2 + neg cx ; Move from bottom to top + neg ax ; Get absolute value of AX +@@2: + mov [Height], ax + mov [DeltaY], cx + +; Get pixel address and write plane + mov ax, bx + mul [mx_BytesPerLine] + mov cx, si ; CX = X1 + shr si, 1 + shr si, 1 + add si, ax ; SI = pixel offset + and cl, 03h + mov ax, 1102h + shl ah, cl + mov [WritePlane], ah + mov dx, TS + out dx, ax ; Set write plane + mov ax, [mx_VideoSegment] + mov ds, ax ; DS:SI points to (X1,Y1) + +; Select the function to handle the drawing loop + xor bx, bx + mov al, BYTE PTR [Op] + cmp al, OP_MOVE + je @@3 + and al, 03h + shl al, 1 + shl al, 1 + shl al, 1 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set logical function + inc bx + inc bx +@@3: + mov ax, [Width] + mov cx, [Height] +; Horizontal, vertical and diagonal lines are not optimized yet + cmp ax, cx + jae @@4 + inc bx +@@4: + shl bx, 1 + call tblDrawFunc[bx] + +; Reset logical function if needed + cmp BYTE PTR [Op], OP_MOVE + je @@Exit + mov ax, 0003h + mov dx, GDC + out dx, ax + +@@Exit: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses a variation of the Cohen-Sutherland algorithm developed +; by Victor Duvanenko. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +subClipLine PROC NEAR + mov di, ax ; Copy X1 to DI and free AX + mov si, dx ; Copy Y2 to SI and free DX +; Compute clip codes for point (X2,Y2)=(CX,SI) + xor al, al +@@P2X1: cmp cx, [mx_ClipX1] + jge @@P2X2 + or al, 1 +@@P2X2: cmp cx, [mx_ClipX2] + jle @@P2Y1 + or al, 2 +@@P2Y1: cmp si, [mx_ClipY1] + jge @@P2Y2 + or al, 4 +@@P2Y2: cmp si, [mx_ClipY2] + jle @@P2XY + or al, 8 +@@P2XY: mov [P2], al +; Compute clip codes for point (X1,Y1)=(DI,BX) + xor al, al +@@P1X1: cmp di, [mx_ClipX1] + jge @@P1X2 + or al, 1 +@@P1X2: cmp di, [mx_ClipX2] + jle @@P1Y1 + or al, 2 +@@P1Y1: cmp bx, [mx_ClipY1] + jge @@P1Y2 + or al, 4 +@@P1Y2: cmp bx, [mx_ClipY2] + jle @@P1XY + or al, 8 +@@P1XY: mov [P1], al +; Check codes for trivial cases + mov ah, [P2] + test al, ah ; Is line invisible? + jnz @@FullClip ; Yes, exit + or ah, al ; Both points clipped? + jz @@Done ; Yes, exit +; Calculate deltas + mov ax, cx + sub ax, di + mov [DeltaX], ax + mov ax, si + sub ax, bx + mov [DeltaY], ax + mov al, [P1] ; Init clipping code +; Clipping loop +@@ClipLoop: + test al, al ; Is first point clipped? + jnz @@ClipX1 ; No, continue + xchg cx, di ; Swap points... + xchg bx, si + xchg al, [P2] ; ...and codes +; Clip left: Y1 = Y1 + DeltaY*(mx_ClipX1-X1)/DeltaX +@@ClipX1: + test al, 1 + jz @@ClipX2 + mov ax, [mx_ClipX1] + sub ax, di + mov di, [mx_ClipX1] + jmp @@ClipX1X2 +; Clip right: Y1 = Y1 + DeltaY*(mx_ClipX2-X1)/DeltaX +@@ClipX2: + test al, 2 + jz @@ClipY1 + mov ax, [mx_ClipX2] + sub ax, di + mov di, [mx_ClipX2] +@@ClipX1X2: + imul [DeltaY] + idiv [DeltaX] + add bx, ax + mov al, 8 + cmp bx, [mx_ClipY2] + jg @@CheckLoop + mov al, 4 + cmp bx, [mx_ClipY1] + jl @@CheckLoop + xor al, al + jmp @@CheckLoop +; Clip top: X1 = X1 + DeltaX*(mx_ClipY1-Y1)/DeltaY +@@ClipY1: + test al, 4 + jz @@ClipY2 + mov ax, [mx_ClipY1] + sub ax, bx + mov bx, [mx_ClipY1] + jmp @@ClipY1Y2 +; Clip bottom: X1 = X1 + DeltaX*(mx_ClipY2-Y1)/DeltaY +@@ClipY2: + mov ax, [mx_ClipY2] + sub ax, bx + mov bx, [mx_ClipY2] +@@ClipY1Y2: + imul [DeltaX] + idiv [DeltaY] + add di, ax + mov al, 1 + cmp di, [mx_ClipX1] + jl @@CheckLoop + mov al, 2 + cmp di, [mx_ClipX2] + jg @@CheckLoop + xor al, al +@@CheckLoop: + mov ah, [P2] + test al, ah + jnz @@FullClip + or ah, al + jnz @@ClipLoop + +@@Done: + mov ax, di + mov dx, si + clc + ret +@@FullClip: + stc + ret +subClipLine ENDP + +; Called when Width >= Height and Op = OP_MOVE +subWidthMove PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthMove ENDP + +; Called when Width < Height and Op = OP_MOVE +subHeightMove PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightMove ENDP + +; Called when Width >= Height and Op <> OP_MOVE +subWidthOp PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] ; Latch data + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthOp ENDP + +; Called when Width < Height and Op <> OP_MOVE +subHeightOp PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightOp ENDP + +mxLine ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxot.asm b/16/x/mxot.asm new file mode 100755 index 00000000..62547665 --- /dev/null +++ b/16/x/mxot.asm @@ -0,0 +1,330 @@ +;----------------------------------------------------------- +; +; MXOT.ASM - Text functions +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES ; We use the reserved name 'WIDTH' +INCLUDE MODEX.DEF + +PUBLIC mxOutChar +PUBLIC mxOutText +PUBLIC mxSetFont +PUBLIC mxSetTextColor +PUBLIC mxGetTextStep +PUBLIC mxSetTextStep + +MAX_WIDTH EQU 16 ; Must be <= 16 +MAX_HEIGHT EQU 32 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD +EXTRN mxPutImage : FAR + +; Default 8x8 font +fnt_Default LABEL + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW OP_MOVE ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +;----------------------------------------------------------- +; +; Sets the current font. +; +; Input: +; Font = pointer to font data +; Width = width of font character in pixels +; Height = height of font character in pixels +; Output: +; AX = 0 on success, else invalid parameters +; +; Note: when the high word of Font (i.e. the segment) is zero, the low +; word is used to select one of the system fonts. +; +mxSetFont PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Font:DWORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, WORD PTR Font[2] ; Get font segment + test ax, ax ; Null segment? + jnz @@UserFont ; No, install user font + +; Install system font + mov ax, WORD PTR Font[0] ; Get font number + cmp ax, MX_MAXSYSFONT ; Check range + jb @@SystemFont + xor ax, ax ; Out of range, use default font +@@SystemFont: + shl ax, 1 + shl ax, 1 + mov bx, ax + mov ax, tbl_SystemFont[bx] ; Get font offset + mov WORD PTR mx_FontPtr[0], ax + mov WORD PTR mx_FontPtr[2], cs + mov al, BYTE PTR tbl_SystemFont[bx+2] + xor ah, ah + mov [mx_FontWidth], ax + mov [mx_DeltaX], ax + mov dl, BYTE PTR tbl_SystemFont[bx+3] + xor dh, dh + mov [mx_FontHeight], dx + mul dx + mov [mx_FontCharSize], ax + mov [mx_DeltaX], ax + xor ax, ax + mov [mx_DeltaY], ax + jmp @@Exit + +; Install user font +@@UserFont: + mov ax, -1 ; Assume an error + mov bx, [Width] + cmp bx, MAX_WIDTH + ja @@Exit ; Invalid character width + mov dx, [Height] + cmp dx, MAX_HEIGHT + ja @@Exit ; Invalid character height + mov [mx_FontWidth], bx + mov [mx_FontHeight], dx + mov ax, bx + add ax, 7 + .shr ax, 3 + mul dx + mov [mx_FontCharSize], ax + mov ax, WORD PTR Font[0] + mov WORD PTR mx_FontPtr[0], ax + mov ax, WORD PTR Font[2] + mov WORD PTR mx_FontPtr[2], ax + xor ax, ax + +@@Exit: + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetFont ENDP + +;----------------------------------------------------------- +; +; Sets the text color and raster op. +; +; Input: +; Color = text color (foreground + background*256) +; Op = raster op +; Output: +; none +; +mxSetTextColor PROC FAR + ARG Op:WORD, \ + Color:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [Color] + mov [mx_FontColor], ax + mov ax, [Op] + mov [mx_FontOp], ax + + xor ax, ax + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetTextColor ENDP + +;----------------------------------------------------------- +; +; Writes a character using the current font and attributes. +; +; Input: +; X, Y = video coordinates +; C = character to print +; Output: +; none +; +mxOutChar PROC FAR + ARG C:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \ + Count:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Gets the pointer to font data for the selected character + lds si, DWORD PTR [mx_FontPtr] + mov al, [C] + xor ah, ah + mul [mx_FontCharSize] ; Offset into font + add si, ax ; DS:SI -> font data for character + +; Converts font data into a 256-color linear image + mov ax, ss + mov es, ax + lea di, [Image] + mov dx, [mx_FontColor] + mov ax, [mx_FontHeight] + mov [Count], ax +@@HeightLoop: + mov cx, [mx_FontWidth] + mov bh, ds:[si] + inc si ; Get a byte from font data + cmp cx, 8 + jbe @@WidthLoop ; Ok for width <= 8 + mov bl, ds:[si] ; Get another byte + inc si +@@WidthLoop: + mov al, dl ; Assume foreground color + shl bx, 1 ; Is font bit set? + jc @@1 ; Yes, foreground is just great + mov al, dh ; Get background color +@@1: + mov es:[di], al ; Put pixel into image + inc di + dec cx + jnz @@WidthLoop + dec [Count] + jnz @@HeightLoop + +; Now pass image to mx_PutImage + lea ax, [Image] + push es + push ax ; Pointer to image + push [X] + push [Y] ; Image coordinates + push [mx_FontWidth] + push [mx_FontHeight] ; Image size + push [mx_FontOp] ; Raster op + call mxPutImage ; Write character + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxOutChar ENDP + +;----------------------------------------------------------- +; +; Writes a string at the coordinates specified. +; +; Input: +; X, Y = text coordinates +; S = pointer to ASCIIZ string +; Output: +; none +; +mxOutText PROC FAR + ARG S:DWORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [S] +@@Loop: + mov al, ds:[si] + test al, al ; End of string? + jz @@Exit ; Yes, exit + inc si + push [X] ; Display character + push [Y] + push ax + call mxOutChar + mov ax, [mx_DeltaX] + add [X], ax ; Bump X coordinate + mov ax, [mx_DeltaY] + add [Y], ax ; Bump Y coordinate + dec [Count] + jnz @@Loop + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE + ret +mxOutText ENDP + +;----------------------------------------------------------- +; +; Sets the distance between characters. +; +; Input: +; DeltaX = horizontal distance in pixels +; DeltaY = vertical distance in pixels +; Output: +; none +; +; Note: this function may be used to set the text direction. +; +mxSetTextStep PROC FAR + ARG DeltaY:WORD, \ + DeltaX:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [DeltaX] + mov [mx_DeltaX], ax + mov ax, [DeltaY] + mov [mx_DeltaY], ax + + .pop ds + .leave ARG_SIZE +mxSetTextStep ENDP + +;----------------------------------------------------------- +; +; Gets the current distance between characters. +; +; Input: +; DeltaX = pointer to horizontal distance in pixels (integer) +; DeltaY = pointer to vertical distance in pixels (integer) +; Output: +; none +; +mxGetTextStep PROC FAR + ARG DeltaY:DWORD, \ + DeltaX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + mov ax, [mx_DeltaX] + lds si, [DeltaX] + mov ds:[si], ax + mov ax, [mx_DeltaY] + lds si, [DeltaY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetTextStep ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxpb.asm b/16/x/mxpb.asm new file mode 100755 index 00000000..8c6aa449 --- /dev/null +++ b/16/x/mxpb.asm @@ -0,0 +1,22 @@ +;----------------------------------------------------------- +; +; MXPB.ASM - Scan buffer for convex polygon fills +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mx_ScanBuffer + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +ALIGN 4 + +mx_ScanBuffer LABEL + DW POLYSCANBUFSIZE DUP(?) + +MX_TEXT ENDS +END diff --git a/16/x/mxpf.asm b/16/x/mxpf.asm new file mode 100755 index 00000000..db0da898 --- /dev/null +++ b/16/x/mxpf.asm @@ -0,0 +1,420 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + Y2 DW ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@Exit + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@Exit + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +@@Exit: + pop bp ; Restore BP + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxFillPoly PROC FAR + ARG Color:WORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc dx + inc di + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 2 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + ja @@ClipYLoop ; Not clipped, continue +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov dx, TS + mov al, 02h + out dx, ax + mov ax, [Color] + mov dx, [mx_BytesPerLine] + shr cx, 1 + jnc @@FillScan + mov es:[di], al + add di, dx + jcxz @@DrawNext +@@FillScan: + mov es:[di], al + add di, dx + mov es:[di], al + add di, dx + dec cx + jnz @@FillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxpg.asm b/16/x/mxpg.asm new file mode 100755 index 00000000..caa7cf1b --- /dev/null +++ b/16/x/mxpg.asm @@ -0,0 +1,589 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill with Gouraud shading +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGouraudPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + E1 DB ? + C1 DB ? + Y2 DW ? + E2 DB ? + C2 DB ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; Also interpolates color for shading. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; DX = start color +; AX = end color +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + push di ; Save scan info offset + push cx ; Save height + push ax ; Save colors + push dx + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@GetColorInfo + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@GetColorInfo + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +; Now get the color info +@@GetColorInfo: + pop bx ; Restore colors + pop ax + pop cx ; Height + pop di ; ES:DI -> scan info + + sub ax, bx ; Get color range + jg @@CL2R + jl @@CR2L + +; Special case: same color + mov ah, bl + mov al, 80h +@@CV: + mov WORD PTR es:[di].E1, ax + add di, SIZE TSCAN + dec cx + jnz @@CV + jmp @@Exit + +; Scan left to right +@@CL2R: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@CL2RLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@CL2RLoop + jmp @@Exit + +; Scan right to left +@@CR2L: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h + +@@CR2LLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@CR2LLoop + +@@Exit: + pop bp + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a scan column. +; +; Input: +; DS:SI = current TSCAN +; ES:DI = address of top pixel +; CX = number of pixels to write +; DX = base color +; Output: +; none +; +subFillScan PROC NEAR + mov ax, WORD PTR ds:[si].E2 + mov bx, WORD PTR ds:[si].E1 + cmp ah, bh + jg @@L2R ; Color increases + jl @@R2L ; Color decreases + +; Special case: color doesn't change + add ax, dx + mov dx, [mx_BytesPerLine] +@@V: + mov es:[di], ah + add di, dx + dec cx + jnz @@V + ret + +; Color increases +@@L2R: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@L2RLoop: + mov es:[di], ah + add dx, bx + adc ax, bp + add di, si + dec cx + jnz @@L2RLoop + .pop bp, si + ret + +; Color decreases +@@R2L: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + neg ax + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@R2LLoop: + mov es:[di], ah + sub dx, bx + sbb ax, bp + add di, si + dec cx + jnz @@R2LLoop + .pop bp, si + ret +subFillScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; Interpolates pixel colors using the Gouraud algorithm. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Colors = array of colors (integer) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxGouraudPoly PROC FAR + ARG Color:WORD, \ + Colors:DWORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc di + inc dx + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 3 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom, need to scale colors too + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov ax, WORD PTR ds:[si].E1 + sub ax, WORD PTR ds:[si].E2 + imul bx + idiv cx + add WORD PTR ds:[si].E2, ax + mov ax, ds:[si].Y1 ; Restore AX and CX + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top, need to scale colors too + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + jbe @@ClipYClip ; Full clipped, skip + mov ax, WORD PTR ds:[si].E2 + sub ax, WORD PTR ds:[si].E1 ; AX = color distance + imul dx + idiv cx + add WORD PTR ds:[si].E1, ax ; Update starting color + jmp @@ClipYLoop +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 + mov ax, [Color] ; Make 8:8 fixed color + mov ah, al + xor al, al + mov [Color], ax +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + out dx, ax + mov dx, [Color] + call subFillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGouraudPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxpi.asm b/16/x/mxpi.asm new file mode 100755 index 00000000..9e8525f5 --- /dev/null +++ b/16/x/mxpi.asm @@ -0,0 +1,267 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Put image +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Move functions. +; Note: loops unrolled and optimized for CX even, no check for CX = 0. +; +subMove PROC NEAR + shr cx, 1 ; Make CX even + jc @@Odd ; Special case if odd byte +@@Loop: movsb + add si, 3 + movsb + add si, 3 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: movsb + add si, 3 + jcxz @@Exit + jmp @@Loop +subMove ENDP +; +subAnd PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + and es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + and es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subAnd ENDP +; +subOr PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + or es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + or es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subOr ENDP +; +subXor PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + xor es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + xor es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: inc di + add si, 4 + dec cx + jnz @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + inc di + add si, 4 + dec cx + jnz @@Loop + ret +subAdd ENDP + +;----------------------------------------------------------- +; +; Copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxPutImage PROC FAR + ARG Op:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Setup planes for output to VGA registers + mov cl, [ReadPlane] + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov ds, WORD PTR Image[2] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov si, WORD PTR Image[0] + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov di, [PixelOffset] +@@Loop: + push si + push di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move + mov ah, [OpInfo] ; Transparent color for subTrans + call [MoveFunction] + pop di + pop si + add si, [Width] ; Go to next image line + add di, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + rol [WritePlane], 1 + adc [PixelOffset], 0 + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxpn.asm b/16/x/mxpn.asm new file mode 100755 index 00000000..eaaf61b4 --- /dev/null +++ b/16/x/mxpn.asm @@ -0,0 +1,60 @@ +;----------------------------------------------------------- +; +; MXPN.ASM - Panning function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxPan + +EXTRN mxWaitDisplay : FAR +EXTRN mxStartAddress : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves the screen. +; +; Input: +; X, Y = new X, Y coordinates of view screen +; Output: +; none +; +mxPan PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov ax, [Y] + mul [mx_BytesPerLine] + mov dx, [X] + shr dx, 1 + shr dx, 1 + add ax, dx + push ax ; Push the start address + call mxWaitDisplay + call mxStartAddress + + mov dx, 03DAh ; Set the pixel pan register + in al, dx + mov dx, 03C0h + mov al, 33h + out dx, al + mov al, BYTE PTR [X] + and al, 3 + shl al, 1 + out dx, al + + xor ax, ax + .leave ARG_SIZE +mxPan ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxpp.asm b/16/x/mxpp.asm new file mode 100755 index 00000000..fc1755a3 --- /dev/null +++ b/16/x/mxpp.asm @@ -0,0 +1,121 @@ +;----------------------------------------------------------- +; +; MXPP.ASM - Get/put pixel functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPixel +PUBLIC mxPutPixel + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Gets a pixel. +; +; Input: +; X, Y = pixel coordinates +; Output: +; pixel color +; +mxGetPixel PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + xor ax, ax + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov bx, [Y] + cmp bx, [mx_ClipY1] + jl @@Exit + cmp bx, [mx_ClipY2] + jg @@Exit + + mov al, 04h ; Set read plane + mov ah, BYTE PTR [X] + and ah, 3 + mov dx, GDC + out dx, ax + + mov ds, [mx_VideoSegment] + mov ax, bx + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov al, ds:[si] ; Get pixel value + xor ah, ah + +@@Exit: + .pop ds, si + .leave ARG_SIZE +mxGetPixel ENDP + +;----------------------------------------------------------- +; +; Puts a pixel of the specified color. +; +; Input: +; X, Y = pixel coordinates +; Color = pixel color +; Output: +; none +; +mxPutPixel PROC FAR + ARG Color:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov ax, [Y] + cmp ax, [mx_ClipY1] + jl @@Exit + cmp ax, [mx_ClipY2] + jg @@Exit + + mov ds, [mx_VideoSegment] + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov cl, BYTE PTR [X] ; Set write plane + and cl, 3 + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[si], al + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxPutPixel ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxra.asm b/16/x/mxra.asm new file mode 100755 index 00000000..dd8e6839 --- /dev/null +++ b/16/x/mxra.asm @@ -0,0 +1,37 @@ +;----------------------------------------------------------- +; +; MXRA.ASM - Row address +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRowAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the row address register. +; +; Input: +; RowAddress = row size in words +; Output: +; none +; +mxRowAddress PROC FAR + ARG RowAddress:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov dx, CRTC + mov al, 13h + mov ah, [RowAddress] + out dx, ax + xor ax, ax + .leave ARG_SIZE +mxRowAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxrp.asm b/16/x/mxrp.asm new file mode 100755 index 00000000..de820c16 --- /dev/null +++ b/16/x/mxrp.asm @@ -0,0 +1,101 @@ +;----------------------------------------------------------- +; +; MXRP.ASM - Rotate palette function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRotatePalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Rotates the palette of the specified number of colors. +; +; Input: +; Palette = pointer to palette +; Count = number of colors to rotate +; Step = step size +; Output: +; none +; +; Note: if Step is positive palette is rotated left to right, otherwise +; right to left. +; +mxRotatePalette PROC FAR + ARG Step:WORD, \ + Count:WORD, \ + Palette:DWORD = ARG_SIZE + LOCAL Holder:BYTE:768 = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov bx, [Count] + add bx, bx + add bx, [Count] ; BX = Count*3 + + lds si, [Palette] ; DS:SI -> palette + push ss + pop es + lea di, Holder ; ES:DI -> local space + cld + + mov ax, [Step] + mov dx, ax + test ax, ax + jz @@Exit ; Nothing to do, exit + jl @@RightToLeft + +@@LeftToRight: + add ax, ax + add dx, ax ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + add si, bx + push si + mov cx, dx + rep movsb + mov es, WORD PTR Palette[2] + mov di, si + dec di ; ES:DI -> last byte of palette + pop si + dec si + mov cx, bx + std + rep movsb + push ss + pop ds + lea si, Holder + les di, [Palette] + mov cx, dx + cld + rep movsb + jmp @@Exit + +@@RightToLeft: + add ax, ax + add dx, ax + neg dx ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + mov cx, dx + rep movsb + les di, [Palette] + mov cx, bx + rep movsb + push ss + pop ds + lea si, Holder + mov cx, dx + rep movsb + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxRotatePalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxsa.asm b/16/x/mxsa.asm new file mode 100755 index 00000000..3ebae67d --- /dev/null +++ b/16/x/mxsa.asm @@ -0,0 +1,44 @@ +;----------------------------------------------------------- +; +; MXSA.ASM - Start address function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxStartAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Modifies the starting address of video memory. +; +; Input: +; StartAddr = new start address of video memory +; Output: +; none +; +mxStartAddress PROC FAR + ARG StartAddr:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov bx, [StartAddr] + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + + .leave ARG_SIZE +mxStartAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxsc.asm b/16/x/mxsc.asm new file mode 100755 index 00000000..bcae45e6 --- /dev/null +++ b/16/x/mxsc.asm @@ -0,0 +1,50 @@ +;----------------------------------------------------------- +; +; MXSC.ASM - Set color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the selected DAC register. +; +; Input: +; Index = index of color to set +; R, G, B = color components +; Output: +; none +; +mxSetColor PROC FAR + ARG B:BYTE:2, \ + G:BYTE:2, \ + R:BYTE:2, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + + mov al, [R] + out dx, al + mov al, [G] + out dx, al + mov al, [B] + out dx, al + + .pop ds, si + .leave ARG_SIZE +mxSetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxsi.asm b/16/x/mxsi.asm new file mode 100755 index 00000000..b88d3b11 --- /dev/null +++ b/16/x/mxsi.asm @@ -0,0 +1,317 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Stretch image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStretchImage + +EXTRN subClipBox : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Stretches and copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; NewWidth = new width of image in pixels +; NewHeight = new height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxStretchImage PROC FAR + ARG Op:WORD, \ + NewHeight:WORD, \ + NewWidth:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WidthStep:DWORD, \ + HeightStep:DWORD, \ + ImageLo:WORD, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Get width stretch factor + IF USE386 EQ TRUE + movzx edx, [Width] + xor eax, eax + movzx ebx, [NewWidth] + shl ebx, 16 + idiv ebx + mov [WidthStep], eax + ELSE + xor dx, dx ; Width stretch factor + mov ax, [Width] + mov bx, [NewWidth] + div bx + mov WORD PTR WidthStep[2], ax + xor ax, ax + div bx + mov WORD PTR WidthStep[0], ax + ENDIF +; Get height stretch factor + IF USE386 EQ TRUE + movzx edx, [Height] + xor eax, eax + movzx ebx, [NewHeight] + shl ebx, 16 + idiv ebx + mov [HeightStep], eax + ELSE + xor dx, dx + mov ax, [Height] + mov bx, [NewHeight] + div bx + mov WORD PTR HeightStep[2], ax + xor ax, ax + div bx + mov WORD PTR HeightStep[0], ax + ENDIF + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [NewWidth] + mov dx, [NewHeight] + call subClipBox + jc @@Exit ; Full clipped + mov [NewWidth], cx + mov [NewHeight], dx + sub [X], bx + sub [Y], ax + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl ; Set read plane + mov cl, bl + mov al, 00010001b + shl al, cl + mov [WritePlane], al ; Set write plane + +; Relocate image origin if previously clipped + mov ax, [Y] + test ax, ax + jz @@OriginYDone + IF USE386 EQ TRUE + shl eax, 16 + imul [HeightStep] + mov ax, [Width] + mul dx + ELSE + mov bx, ax + mul WORD PTR HeightStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR HeightStep[2] + add ax, cx + mul [Width] + ENDIF + add WORD PTR [Image], ax +@@OriginYDone: + mov ax, [X] + test ax, ax + jz @@OriginXDone + IF USE386 EQ TRUE + shl eax, 16 + imul [WidthStep] + add WORD PTR [Image], dx + ELSE + mov bx, ax + mul WORD PTR WidthStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR WidthStep[2] + add ax, cx + add WORD PTR [Image], ax + ENDIF +@@OriginXDone: + mov ax, WORD PTR HeightStep[2] + mul [Width] + mov WORD PTR HeightStep[2], ax + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + mov ds, WORD PTR Image[2] + xor ax, ax + mov [ImageLo], ax +@@Loop: + mov si, WORD PTR Image[0] ; Get pointer to image + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov cx, [NewHeight] + mov di, [PixelOffset] ; ES:DI points to video memory + mov ah, [OpInfo] ; Additional raster op info + xor bx, bx + mov dx, [mx_BytesPerLine] + call [MoveFunction] ; Draw column + inc [ReadPlane] ; Next read plane + rol [WritePlane], 1 ; Next write plane + adc [PixelOffset], 0 ; Update video offset if needed + mov dx, WORD PTR WidthStep[0] + mov ax, WORD PTR WidthStep[2] + add [ImageLo], dx + adc WORD PTR Image[0], ax ; Next image column + dec [NewWidth] + jnz @@Loop ; Repeat for all columns + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Move functions, on entry: +; AH = additional raster op info (e.g. transparent color) +; BX = 0, +; CX = pixel count, +; DX = mx_BytesPerLine. +; +subMove PROC NEAR +@@Loop: mov al, ds:[si] + mov es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subMove ENDP +; +subAnd PROC NEAR +@@Loop: mov al, ds:[si] + and es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAnd ENDP +; +subOr PROC NEAR +@@Loop: mov al, ds:[si] + or es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subOr ENDP +; +subXor PROC NEAR +@@Loop: mov al, ds:[si] + xor es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAdd ENDP + +mxStretchImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxsl.asm b/16/x/mxsl.asm new file mode 100755 index 00000000..d7908855 --- /dev/null +++ b/16/x/mxsl.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Start line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStartLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Changes the video start address to the specified line. +; +; Input: +; Line = new start line +; Output: +; none +; +mxStartLine PROC FAR + ARG Line:WORD = ARG_SIZE + .enter 0 + ASSUME ds:NOTHING + + mov ax, [Line] ; Get video offset + mul [mx_BytesPerLine] + xchg ax, bx ; Copy it into BX + +; Wait display + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + +; Set starting address + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + +; Wait retrace + mov dx, STATUS +@@2: in al,dx + test al, 08h + jz @@2 + + xor ax, ax + .leave ARG_SIZE +MX_TEXT ENDS +END diff --git a/16/x/mxsm.asm b/16/x/mxsm.asm new file mode 100755 index 00000000..183fba1e --- /dev/null +++ b/16/x/mxsm.asm @@ -0,0 +1,508 @@ +;----------------------------------------------------------- +; +; MXSM.ASM - Set/change mode functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxChangeMode +PUBLIC mxGetAspect +PUBLIC mxGetScreenSize +PUBLIC mxSetMode + +PUBLIC mx_ScreenWidth +PUBLIC mx_ScreenHeight +PUBLIC mx_BytesPerLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mxSetSysClipRegion : FAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD + +mx_ScreenWidth DW ? ; Current screen width +mx_ScreenHeight DW ? +mx_AspectX DW ? ; Aspect ratio for current mode +mx_AspectY DW ? +mx_BytesPerLine DW 0 ; Bytes per line + +; +; Tables for setting video modes, sources: +; - MODEX.ASM, Matt Pritchard +; - Dr. Dobb's Journal, Michael Abrash +; - Fractint VIDEO.ASM module +; +TBL_SingleLine LABEL WORD ; CRTC + DW 04009h ; Cell height: 1 scan line + DW 00014h ; Double word mode off + DW 0E317h ; Byte mode on + DW 0 +TBL_DoubleLine LABEL WORD ; CRTC + DW 04109h ; Cell height: 2 scan lines + DW 00014h + DW 0E317h + DW 0 +TBL_Width320 LABEL WORD ; CRTC + DW 05F00h ; Horizontal total + DW 04F01h ; Horizontal displayed + DW 05002h ; Start horizontal blanking + DW 08203h ; End horizontal blanking + DW 05404h ; Start horizontal sync + DW 08005h ; End horizontal sync + DW 02813h ; Row address + DW 0 +TBL_Width360 LABEL WORD ; CRTC + DW 06B00h ; Horizontal total + DW 05901h ; Horizontal displayed + DW 05A02h ; Start horizontal blanking + DW 08E03h ; End horizontal blanking + DW 05E04h ; Start horizontal sync + DW 08A05h ; End horizontal sync + DW 02D13h ; Row address + DW 0 +TBL_Height175 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 08310h ; Start vertical sync + DW 08511h ; End vertical sync + DW 05D12h ; Vertical displayed + DW 06315h ; Start vertical blanking + DW 0BA16h ; End vertical blanking + DW 0 +TBL_Height200 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 09C10h ; Start vertical sync + DW 08E11h ; End vertical sync + DW 08F12h ; Vertical displayed + DW 09615h ; Start vertical blanking + DW 0B916h ; End vertical blanking + DW 0 +TBL_Height240 LABEL WORD ; CRTC + DW 00D06h ; Vertical total + DW 03E07h ; Overflow + DW 0EA10h ; Start vertical sync + DW 08C11h ; End vertical sync + DW 0DF12h ; Vertical displayed + DW 0E715h ; Start vertical blanking + DW 00616h ; End vertical blanking + DW 0 +TBL_Tweak400x600: + DW 07400h + DW 06301h + DW 06402h + DW 09703h + DW 06804h + DW 09505h + DW 08606h + DW 0F007h + DW 06009h + DW 0310Fh + DW 05B10h + DW 08D11h + DW 05712h + DW 03213h + DW 00014h + DW 06015h + DW 08016h + DW 0E317h + DW 0 + +TBL_320x200: + DB 63h ; 400 scan lines, 25 MHz clock + DW 6, 5 ; Aspect: 6/5 = 1.2:1 + DW 320, 200 ; Size + DW TBL_Width320, TBL_Height200, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x240: + DB 0E3h ; 400 scan lines, 25 MHz clock + DW 1, 1 ; Aspect: 1/1 = 1:1 + DW 320, 240 ; Size + DW TBL_Width320, TBL_Height240, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x400: + DB 63h ; 480 scan lines, 25 MHz clock + DW 6, 10 ; Aspect: 6/10 = 0.6:1 + DW 320, 400 ; Size + DW TBL_Width320, TBL_Height200, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_320x480: + DB 0E3h ; 480 scan lines, 25 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 320, 480 ; Size + DW TBL_Width320, TBL_Height240, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_360x200: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 20 ; Aspect: 27/20 = 1.35:1 + DW 360, 200 ; Size + DW TBL_Width360, TBL_Height200, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x240: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 8 ; Aspect: 9/8 = 1.125:1 + DW 360, 240 ; Size + DW TBL_Width360, TBL_Height240, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x400: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 40 ; Aspect: 27/40 = 0.675:1 + DW 360, 400 ; Size + DW TBL_Width360, TBL_Height200, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_360x480: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 16 ; Aspect: 9/16 = 0.5625:1 + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height240, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_320x175: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_DoubleLine, 0 + DW 819 +TBL_320x350: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_SingleLine, 0 + DW 819 +TBL_360x175: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x350: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_400x600: + DB 0E7h ; 28 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 400, 600 ; Size + DW TBL_Tweak400x600, 0 + DW 655 ; Max height + +TBL_Mode LABEL WORD + DW TBL_320x175 + DW TBL_320x200 + DW TBL_320x240 + DW TBL_320x350 + DW TBL_320x400 + DW TBL_320x480 + DW TBL_360x175 + DW TBL_360x200 + DW TBL_360x240 + DW TBL_360x350 + DW TBL_360x400 + DW TBL_360x480 + DW TBL_400x600 + +MAXVMODE EQU ($-OFFSET TBL_Mode) / 2 + +;----------------------------------------------------------- +; +; Enables 80x25 color text mode +; +subText PROC NEAR + ASSUME ds:MX_TEXT + mov ax, 0003h + int 10h ; Call BIOS set mode + + mov [mx_ScreenHeight], 0 + mov [mx_BytesPerLine], 0 + ret +subText ENDP + +;----------------------------------------------------------- +; +; Enables the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; +mxSetMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jnz @@Set ; No, handle it + + call subText ; Back to text mode + jmp @@Exit ; Exit now + +; Set video mode +@@Set: + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + +; Use BIOS to set 320x200x256 linear mode + push si ; Save SI + mov ax, 0013h + int 10h ; Use BIOS to set 320x200 linear mode + pop si ; Restore SI + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + shr ax, 1 + shr ax, 1 ; Divide by four to get bytes per line + mov [mx_BytesPerLine], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Set virtual screen and system clip region + push [mx_ScreenWidth] + push WORD PTR ds:[bx] + call mxSetSysClipRegion + +; Clear video memory + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov es, [mx_VideoSegment] + xor di, di + mov cx, 8000h + xor ax, ax + rep stosw + +@@Done: +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxSetMode ENDP + +;----------------------------------------------------------- +; +; Changes from the current mode the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; Notes: +; this function assumes that mxSetMode and mxSetVirtualScreen +; have been called first. View size is rearranged to match the +; specified mode, but video memory is not cleared. +; Differences from mxSetMode: +; - video BIOS is not called to initialize graphics; +; - row address register is not modified; +; - video memory is not cleared; +; - mx_BytesPerLine is not modified; +; - system clip region is not modified. +; +mxChangeMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jz @@Exit ; Yes, exit + + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + cmp al, 13h ; Row address register? + je @@Loop ; Yes, ignore it + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxChangeMode ENDP + +;----------------------------------------------------------- +; +; Returns the aspect ratio for the current mode. +; +; Input: +; AspectX = pointer to aspect X +; AspectY = pointer to aspect Y +; +; A rectangle of width AspectX and height AspectY looks like a square. +; +mxGetAspect PROC FAR + ARG AspectY:DWORD, \ + AspectX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [AspectX] + mov ax, [mx_AspectX] + mov ds:[si], ax + lds si, [AspectY] + mov ax, [mx_AspectY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetAspect ENDP + +;----------------------------------------------------------- +; +; Returns the current screen size. +; +; Input: +; Width = pointer to screen width +; Height = pointer to screen height +; +mxGetScreenSize PROC FAR + ARG SizeY:DWORD, \ + SizeX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [SizeX] + mov ax, [mx_ScreenWidth] + mov ds:[si], ax + lds si, [SizeY] + mov ax, [mx_ScreenHeight] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetScreenSize ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxsp.asm b/16/x/mxsp.asm new file mode 100755 index 00000000..1d08e711 --- /dev/null +++ b/16/x/mxsp.asm @@ -0,0 +1,57 @@ +;----------------------------------------------------------- +; +; MXSP.ASM - Set palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to set +; Count = number of color to set +; Output: +; none +; +mxSetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + lds si, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + cld + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + + .pop ds, si + .leave ARG_SIZE +mxSetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxss.asm b/16/x/mxss.asm new file mode 100755 index 00000000..97df7366 --- /dev/null +++ b/16/x/mxss.asm @@ -0,0 +1,72 @@ +;----------------------------------------------------------- +; +; MXSS.ASM - Split screen function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSplitScreen + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Splits the screen. +; +; Input: +; Line = scan line at which screen has to be splitted +; Output: +; none +; +mxSplitScreen PROC FAR + ARG Line:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + +; Modify the line compare value: bits 0-7 are in the Line Compare +; register (CRTC #18), bit 8 is in the Overflow Low register (CRTC #7) +; and bit 9 is in the Maximum Row Address register (CRTC #9) + mov ax, [Line] + shl ax, 1 ; Adjust line for mode "X" + mov bh, ah + mov bl, ah + and bx, 0201h + mov cl, 4 + shl bx, cl + shl bh, 1 + mov dx, CRTC +; Write bits 0-7 to line compare register + mov ah, al + mov al, 18h + out dx, ax +; Write bit 8 to overflow register + mov al, 07h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 11101111b + or ah, bl + mov al, 07h + out dx, ax +; Write bit 9 to maximum row address register + mov al, 09h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 10111111b + or ah, bh + mov al, 09h + out dx, ax + + .leave ARG_SIZE +mxSplitScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxtl.asm b/16/x/mxtl.asm new file mode 100755 index 00000000..69900c88 --- /dev/null +++ b/16/x/mxtl.asm @@ -0,0 +1,169 @@ +;----------------------------------------------------------- +; +; MXTL.ASM - Put tile +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutTile +PUBLIC mxTransPutTile + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + + shr cx, 1 ; Move line + rep movsw + rcl cx, 1 + rep movsb + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutTile ENDP + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; Skips over color 0. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxTransPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + +; Move one line + jcxz @@MoveLineDone +@@MoveLineLoop: + mov al, ds:[si] + test al, al + jz @@MoveLineNext + mov es:[di], al +@@MoveLineNext: + inc si + inc di + dec cx + jnz @@MoveLineLoop +@@MoveLineDone: + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxTransPutTile ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxvs.asm b/16/x/mxvs.asm new file mode 100755 index 00000000..992eabab --- /dev/null +++ b/16/x/mxvs.asm @@ -0,0 +1,110 @@ +;----------------------------------------------------------- +; +; MXVS.ASM - Set/get virtual screen +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetVirtualScreen +PUBLIC mxGetVirtualScreen + +EXTRN mxRowAddress : FAR +EXTRN mxSetSysClipRegion : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_CodeSegment : WORD + +mx_VirtualWidth DW ? ; Virtual screen size +mx_VirtualHeight DW ? + +;----------------------------------------------------------- +; +; Sets the virtual screen. +; +; Input: +; Width = virtual screen width +; Height = virtual screen height +; Output: +; 0 on success, else invalid parameters +; +mxSetVirtualScreen PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + +; Set DS to code segment + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, 1 ; Assume an error + cmp [Width], 320 ; Check width + jb @@Exit + push ax ; Save return code + mov dx, 0004h + xor ax, ax ; DX:AX = 256K + div [Width] ; Max height in AX + cmp [Height], ax + pop ax ; Restore return code + ja @@Exit ; Exit if bad heigth + + mov ax, [Width] + and ax, 0FFF8h ; Align to byte + mov [mx_VirtualWidth], ax + shr ax, 1 + shr ax, 1 + mov [mx_BytesPerLine], ax + shr ax, 1 + push ax + call mxRowAddress ; Set row address + mov ax, [Height] + mov [mx_VirtualHeight], ax + + push [Width] + push [Height] + call mxSetSysClipRegion + xor ax, ax + +@@Exit: + .pop ds + .leave ARG_SIZE +mxSetVirtualScreen ENDP + +;----------------------------------------------------------- +; +; Returns the current virtual screen size. +; +; Input: +; Width = pointer to virtual screen width +; Height = pointer to virtual screen height +; Output: +; none +; +mxGetVirtualScreen PROC FAR + ARG Height:DWORD, \ + Width:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + mov ax, [mx_VirtualWidth] + lds si, [Width] + mov ds:[si], ax + mov ax, [mx_VirtualHeight] + lds si, [Height] + mov ds:[si], ax + + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxGetVirtualScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxwd.asm b/16/x/mxwd.asm new file mode 100755 index 00000000..de55208f --- /dev/null +++ b/16/x/mxwd.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWD.ASM - Wait display function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitDisplay + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for display start. +; +mxWaitDisplay PROC FAR + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + ret +mxWaitDisplay ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxwm.asm b/16/x/mxwm.asm new file mode 100755 index 00000000..06158859 --- /dev/null +++ b/16/x/mxwm.asm @@ -0,0 +1,39 @@ +;----------------------------------------------------------- +; +; MXWM.ASM - Set write mode function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWriteMode + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write mode. +; +; Input: +; Mode = write mode (0,1,2,3) +; Output: +; none +; +mxWriteMode PROC FAR + ARG Mode:BYTE:2 = ARG_SIZE + .enter 0 + + mov dx, GDC + mov ah, [Mode] + and ah, 00000011b + or ah, 01000000b + mov al, 05h + out dx, ax + + .leave ARG_SIZE +mxWriteMode ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxwp.asm b/16/x/mxwp.asm new file mode 100755 index 00000000..19ca99d0 --- /dev/null +++ b/16/x/mxwp.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXWP.ASM - Set write/read plane functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWritePlane +PUBLIC mxReadPlane + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write plane(s). +; +; Input: +; Plane = write plane(s) to set (bit 0 enables plane 0, +; bit 1 enables plane 1 and so on, different planes +; may be selected at the same time) +; Output: +; none +; +mxWritePlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + .enter 0 + + mov ah, [Plane] + and ah, 00001111b ; Mask off unused bits + mov al, 02h + mov dx, TS + out dx, ax + + .leave ARG_SIZE +mxWritePlane ENDP + +;----------------------------------------------------------- +; +; Sets the read plane. +; +; Input: +; Plane = read plane to set (0,1,2,3) +; Output: +; none +; +mxReadPlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov al, 04h + mov ah, [Plane] + and ah, 0000011b ; Mask off unused bits + mov dx, GDC + out dx, ax + .leave ARG_SIZE +mxReadPlane ENDP + +MX_TEXT ENDS +END diff --git a/16/x/mxwr.asm b/16/x/mxwr.asm new file mode 100755 index 00000000..bd29fe59 --- /dev/null +++ b/16/x/mxwr.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWR.ASM - Wait vertical retrace function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitRetrace + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for vertical retrace start. +; +mxWaitRetrace PROC FAR + mov dx, STATUS +@@1: in al,dx + test al, 08h + jz @@1 + ret +mxWaitRetrace ENDP + +MX_TEXT ENDS +END diff --git a/16/x/readme.txt b/16/x/readme.txt new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/x/readme.txt @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/x_/MODEX.BAK b/16/x_/MODEX.BAK new file mode 100755 index 00000000..923d02e9 Binary files /dev/null and b/16/x_/MODEX.BAK differ diff --git a/16/x_/default.fnt b/16/x_/default.fnt new file mode 100755 index 00000000..12eb22cb --- /dev/null +++ b/16/x_/default.fnt @@ -0,0 +1,260 @@ +; +; MODEX library default font +; Copyright (c) 1993-1994 by Alessandro Scotti +; + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0 + DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1 + DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2 + DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3 + DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4 + DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5 + DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6 + DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7 + DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8 + DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9 + DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10 + DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11 + DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12 + DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13 + DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14 + DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15 + DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16 + DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17 + DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18 + DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19 + DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20 + DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21 + DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22 + DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23 + DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24 + DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25 + DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26 + DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27 + DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28 + DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29 + DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30 + DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; + DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; ! + DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; " + DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; # + DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $ + DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; % + DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; & + DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; ' + DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; ( + DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; ) + DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; * + DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; + + DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; , + DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; - + DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; . + DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; / + DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0 + DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1 + DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2 + DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3 + DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4 + DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5 + DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6 + DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7 + DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8 + DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9 + DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; : + DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ; + DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; < + DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; = + DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; > + DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ? + DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @ + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A + DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B + DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C + DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F + DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G + DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H + DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I + DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J + DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K + DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L + DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M + DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N + DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O + DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P + DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q + DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R + DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S + DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T + DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U + DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V + DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W + DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X + DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y + DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z + DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [ + DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \ + DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ] + DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^ + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _ + DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; ` + DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a + DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b + DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c + DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d + DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e + DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g + DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h + DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i + DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j + DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k + DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l + DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m + DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n + DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o + DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q + DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r + DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s + DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t + DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u + DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v + DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w + DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x + DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y + DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z + DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; { + DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; | + DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; } + DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~ + DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ;  + DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128 + DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129 + DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130 + DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131 + DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132 + DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133 + DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134 + DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135 + DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136 + DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137 + DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138 + DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139 + DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140 + DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141 + DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142 + DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143 + DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144 + DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145 + DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146 + DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147 + DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148 + DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149 + DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150 + DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151 + DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152 + DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153 + DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154 + DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155 + DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156 + DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157 + DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158 + DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159 + DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160 + DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161 + DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162 + DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163 + DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164 + DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165 + DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166 + DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167 + DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168 + DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169 + DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170 + DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171 + DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172 + DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173 + DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174 + DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175 + DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176 + DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177 + DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178 + DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179 + DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180 + DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181 + DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182 + DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183 + DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184 + DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185 + DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186 + DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187 + DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188 + DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189 + DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190 + DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191 + DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192 + DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193 + DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194 + DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195 + DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196 + DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197 + DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198 + DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199 + DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200 + DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201 + DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202 + DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203 + DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204 + DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205 + DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206 + DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207 + DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208 + DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209 + DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210 + DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211 + DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212 + DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213 + DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214 + DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215 + DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216 + DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217 + DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218 + DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219 + DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220 + DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221 + DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222 + DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223 + DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224 + DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225 + DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226 + DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227 + DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228 + DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229 + DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230 + DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231 + DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232 + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233 + DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234 + DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235 + DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236 + DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237 + DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238 + DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239 + DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240 + DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241 + DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242 + DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243 + DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244 + DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245 + DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246 + DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247 + DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248 + DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249 + DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250 + DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251 + DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252 + DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253 + DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255 diff --git a/16/x_/makefile b/16/x_/makefile new file mode 100755 index 00000000..eb7bf624 --- /dev/null +++ b/16/x_/makefile @@ -0,0 +1,82 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +LIBINCS = MODEX.DEF + +LIBOBJS = MXBB.OBJ \ + MXCC.OBJ \ + MXCG.OBJ \ + MXCL.OBJ \ + MXCR.OBJ \ + MXFB.OBJ \ + MXFP.OBJ \ + MXGC.OBJ \ + MXGI.OBJ \ + MXGM.OBJ \ + MXGP.OBJ \ + MXGV.OBJ \ + MXHL.OBJ \ + MXIT.OBJ \ + MXLL.OBJ \ + MXLN.OBJ \ + MXOT.OBJ \ + MXPB.OBJ \ + MXPF.OBJ \ + MXPG.OBJ \ + MXPI.OBJ \ + MXPN.OBJ \ + MXPP.OBJ \ + MXRA.OBJ \ + MXRP.OBJ \ + MXSA.OBJ \ + MXSC.OBJ \ + MXSI.OBJ \ + MXSL.OBJ \ + MXSM.OBJ \ + MXSP.OBJ \ + MXSS.OBJ \ + MXTL.OBJ \ + MXVS.OBJ \ + MXWD.OBJ \ + MXWM.OBJ \ + MXWP.OBJ \ + MXWR.OBJ + +# +# ASM compiler +# +ASMC = tasm +ASMO = /m5 /zi +#/p + +# +# PAS compiler +# +PASC = tpc +PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = tlib + +.asm.obj: + $(ASMC) $(ASMO) $< + +target: modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/x_/modex.def b/16/x_/modex.def new file mode 100755 index 00000000..9c6b75b5 --- /dev/null +++ b/16/x_/modex.def @@ -0,0 +1,154 @@ +;------------------------------------------------------------ +; +; MODEX.DEF - Include file +; Copyright (c) 1993-1994 by Alessandro Scotti +; +JUMPS +LOCALS + +TRUE EQU 1 ; Boolean constants +FALSE EQU 0 + +USE286 = FALSE ; TRUE enables 80286 instructions +USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions + +IF USE286 EQ TRUE + P286 +ENDIF + +IF USE386 EQ TRUE + P386 + USE286 = TRUE +ENDIF + +MXVERSION EQU 0128h ; Library version (1.40) + +;------------------------------------------------------------ +; +; VGA definitions +; +MISC EQU 3C2h ; Miscellaneous output +TS EQU 3C4h ; Timing Sequencer index register +GDC EQU 3CEh ; Graphics Data Controller index register +CRTC EQU 3D4h ; CRTC index register +STATUS EQU 3DAh ; Input Status register one + +;------------------------------------------------------------ +; +; Raster operators +; +OP_SET EQU 0 +OP_MOVE EQU 0 ; Same as OP_SET +OP_AND EQU 1 +OP_OR EQU 2 +OP_XOR EQU 3 +OP_TRANS EQU 4 +OP_ADD EQU 5 ; Must be last op + +;------------------------------------------------------------ +; +; Polygon fill functions +; +POLYSCANBUFSIZE EQU 4*1024 + +;------------------------------------------------------------ +; Macro to push registers, variables or flags onto the stack +; Usage: .push "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.PUSH has more than 10 arguments> + ENDIF + IRP $reg, + IFB <$reg> ;; Is argument blank? + EXITM ;; Yes, exit + ELSEIFIDNI <$reg>, ;; Is argument the keyword "FLAGS"? + pushf ;; Yes, push flags + ELSE + push $reg ;; Push argument + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; Macro to pop registers, variables or flags from the stack +; Usage: .pop "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.POP has more than 10 arguments> + ENDIF + IRP $reg, + IFNB <$reg> ;; Is argument non-blank? + IFIDNI <$reg>, ;; Yes, is it the keyword "FLAGS"? + popf ;; Yes, pop flags + ELSE + pop $reg ;; Pop argument + ENDIF + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; +.enter MACRO localsize + IF USE286 EQ TRUE + enter localsize, 0 + ELSE + push bp + mov bp, sp + sub sp, localsize + ENDIF +ENDM + +;------------------------------------------------------------ +; +.leave MACRO argsize + IF USE286 EQ TRUE + leave + ELSE + mov sp, bp + pop bp + ENDIF + IFNB + ret argsize + ELSE + ret + ENDIF +ENDM + +;------------------------------------------------------------ +; +.shr MACRO arg, count + IF USE286 EQ TRUE + shr arg, count + ELSE + $temp = count + WHILE $temp GT 0 + shr arg, 1 + $temp = $temp-1 + ENDM + ENDIF +ENDM + +;------------------------------------------------------------ +; +.shl MACRO arg, count + IF USE286 EQ TRUE + shl arg, count + ELSE + $temp = count + WHILE $temp GT 0 + shl arg, 1 + $temp = $temp-1 + ENDM + ENDIF +ENDM diff --git a/16/x_/modex.h b/16/x_/modex.h new file mode 100755 index 00000000..2c1f1ebe --- /dev/null +++ b/16/x_/modex.h @@ -0,0 +1,153 @@ +/* + MODEX.H - C/C++ include file for the MODEX library + Copyright (c) 1994 Alessandro Scotti +*/ + +#ifndef _MODEX_H_ // Avoid nested inclusions +#define _MODEX_H_ + +// +// Video modes +// +#define MX_TEXT 0 // 80x25 text +#define MX_320x175 1 // 320x175x256 +#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5 +#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1 +#define MX_320x350 4 // 320x350x256 +#define MX_320x400 5 // 320x400x256, 2 pages +#define MX_320x480 6 // 320x480x256, 1 page +#define MX_360x175 7 // 360x175x256 +#define MX_360x200 8 // 360x200x256, 3 pages +#define MX_360x240 9 // 360x240x256, 2 pages +#define MX_360x350 10 // 360x350x256 +#define MX_360x400 11 // 360x400x256, 1 page +#define MX_360x480 12 // 360x480x256, 1 page +#define MX_400x600 13 // 400x600x256, 1 page + +// +// Fade effects +// +#define MX_FADEIN 0 +#define MX_FADEOUT 1 + +// +// Raster ops +// +#define OP_SET 0 // No operator +#define OP_AND 1 // And +#define OP_OR 2 // Or +#define OP_XOR 3 // Xor +#define OP_TRANS 4 // Transparent +#define OP_ADD 5 // Additive +#define OP_MOVE 0 // Alias for OP_SET + +// +// Temporary definitions +// +#define MXBYTE unsigned char +#define MXBOOL short int +#define MXSINT short int +#define MXUINT unsigned short int +#define MXAPI far pascal +#define MXPTR void far * + +// Functions + +#ifdef __cplusplus // Avoid C++ name mangling +extern "C" { +#endif + +// +// Initialization +// +MXSINT MXAPI mxInit( void ); // Returns 0 if successful +void MXAPI mxTerm( void ); +MXUINT MXAPI mxGetVersion( void ); +// +// Mode setting +// +void MXAPI mxChangeMode( MXUINT mode ); +void MXAPI mxSetMode( MXUINT mode ); +void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty ); +void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height ); +// +// Hardware support +// +void MXAPI mxWriteMode( MXBYTE wm ); +void MXAPI mxSplitScreen( MXUINT line ); +void MXAPI mxStartAddress( MXUINT sa ); +void MXAPI mxStartLine( MXUINT sl ); +void MXAPI mxWaitDisplay( void ); +void MXAPI mxWaitRetrace( void ); +void MXAPI mxWritePlane( MXBYTE wp ); +void MXAPI mxReadPlane( MXBYTE rp ); +void MXAPI mxRowAddress( MXBYTE ra ); +// +// Virtual screen +// +void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height ); +void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height ); +void MXAPI mxPan( MXUINT x, MXUINT y ); +// +// Clipping +// +MXBOOL MXAPI mxGetClip( void ); +MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h ); +MXBOOL MXAPI mxSetClip( MXBOOL ); +void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height ); +// +// Graphics +// +void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy ); +void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op ); +MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y ); +void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color ); +void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op ); +void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op ); +void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h ); +void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color ); +void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op ); +// +// Palette +// +void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b ); +void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue ); +void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT ); +void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step ); +// +// Text +// +MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight ); +void MXAPI mxSetTextColor( MXUINT color, MXUINT op ); +void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay ); +void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay ); +void MXAPI mxOutChar( MXSINT x, MXSINT y, char c ); +void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz ); +// +// Convex polygons +// +void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); + +#ifdef __cplusplus +} +#endif + +// +// Remove temporary defines +// +#undef MXBYTE +#undef MXBOOL +#undef MXSINT +#undef MXUINT +#undef MXPTR +#undef MXAPI + +#endif // _MODEX_H_ diff --git a/16/x_/modex.lbr b/16/x_/modex.lbr new file mode 100755 index 00000000..b1ec26b6 --- /dev/null +++ b/16/x_/modex.lbr @@ -0,0 +1,38 @@ ++-MXBB.OBJ & ++-MXCC.OBJ & ++-MXCG.OBJ & ++-MXCL.OBJ & ++-MXCR.OBJ & ++-MXFB.OBJ & ++-MXFP.OBJ & ++-MXGC.OBJ & ++-MXGI.OBJ & ++-MXGM.OBJ & ++-MXGP.OBJ & ++-MXGV.OBJ & ++-MXHL.OBJ & ++-MXIT.OBJ & ++-MXLL.OBJ & ++-MXLN.OBJ & ++-MXOT.OBJ & ++-MXPB.OBJ & ++-MXPF.OBJ & ++-MXPG.OBJ & ++-MXPI.OBJ & ++-MXPN.OBJ & ++-MXPP.OBJ & ++-MXRA.OBJ & ++-MXRP.OBJ & ++-MXSA.OBJ & ++-MXSC.OBJ & ++-MXSI.OBJ & ++-MXSL.OBJ & ++-MXSM.OBJ & ++-MXSP.OBJ & ++-MXSS.OBJ & ++-MXTL.OBJ & ++-MXVS.OBJ & ++-MXWD.OBJ & ++-MXWM.OBJ & ++-MXWP.OBJ & ++-MXWR.OBJ diff --git a/16/x_/modex.pas b/16/x_/modex.pas new file mode 100755 index 00000000..7d9d26ed --- /dev/null +++ b/16/x_/modex.pas @@ -0,0 +1,194 @@ +(* + Turbo Pascal interface to the MODEX library + Copyright (c) 1993,1994 by Alessandro Scotti +*) +unit ModeX; +interface + +const + (* Video modes *) + MX_TEXT = 0; + MX_320x175 = 1; + MX_320x200 = 2; + MX_320x240 = 3; + MX_320x350 = 4; + MX_320x400 = 5; + MX_320x480 = 6; + MX_360x175 = 7; + MX_360x200 = 8; + MX_360x240 = 9; + MX_360x350 = 10; + MX_360x400 = 11; + MX_360x480 = 12; + MX_400x600 = 13; + + (* Fade effects *) + MX_FADEIN = 0; + MX_FADEOUT = 1; + + (* Raster ops *) + OP_SET = 0; + OP_AND = 1; + OP_OR = 2; + OP_XOR = 3; + OP_TRANS = 4; + OP_ADD = 5; + OP_MOVE = 0; (* Alias for OP_SET *) + +procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer ); +procedure mxCircle( CX, CY: integer; Radius: word; Color: byte ); +procedure mxChangeMode( Mode: word ); +procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word ); +procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word ); +procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word ); +procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word ); +procedure mxGetAspect( var AspectX, AspectY: word ); +function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean; +function mxGetClip: boolean; +procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word ); +procedure mxGetPalette( Palette: pointer; Start, Count: word ); +function mxGetPixel( X, Y: word ): byte; +procedure mxGetScreenSize( var Width, Height: word ); +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); +function mxGetVersion: word; +procedure mxGetVirtualScreen( var Width, Height: word ); +procedure mxInit; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); +procedure mxOutChar( X, Y: integer; C: char ); +procedure mxOutText( X, Y: integer; S: pointer ); +procedure mxPan( X, Y: word ); +procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word ); +procedure mxPutPixel( X, Y: word; C: byte ); +procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxReadPlane( Plane: byte ); +procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer ); +procedure mxRowAddress( RowAddress: byte ); +function mxSetClip( Clip: boolean ): boolean; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); +procedure mxSetColor( Index, R, G, B: word ); +procedure mxSetFont( Font: pointer; Width, Height: word ); +procedure mxSetMode( Mode: word ); +procedure mxSetPalette( Palette: pointer; Start, Count: word ); +procedure mxSetTextColor( Color, Op: word ); +procedure mxSetTextStep( DeltaX, DeltaY: integer ); +procedure mxSetVirtualScreen( Width, Height: word ); +procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word ); +procedure mxSplitScreen( Line: word ); +procedure mxStartAddress( StartAddress: word ); +procedure mxStartLine( Line: word ); +procedure mxTerm; +procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxWaitDisplay; +procedure mxWaitRetrace; +procedure mxWriteMode( Mode: byte ); +procedure mxWritePlane( Plane: byte ); + +procedure mxFillPoly( Count: word; var Map, Points; Color: word ); +procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word ); +procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word ); + +procedure mxOutStr( X, Y: integer; S: string ); + +implementation + +procedure mxBitBlt; external; +procedure mxChangeMode( Mode: word ); external; +procedure mxCircle; external; +procedure mxColorToGray; external; +procedure mxFadePalette; external; +procedure mxFillBox; external; +procedure mxGammaCorrect; external; +procedure mxGetAspect( var AspectX, AspectY: word ); external; +function mxGetClipRegion; external; +function mxGetClip: boolean; external; +procedure mxGetImage; external; +procedure mxGetPalette( Palette: pointer; Start, Count: word ); external; +function mxGetPixel( X, Y: word ): byte; external; +procedure mxGetScreenSize( var Width, Height: word ); external; +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external; +function mxGetVersion: word; external; +procedure mxGetVirtualScreen( var Width, Height: word ); external; +procedure mxInit; external; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external; +procedure mxOutChar( X, Y: integer; C: char ); external; +procedure mxOutText( X, Y: integer; S: pointer ); external; +procedure mxPan( X, Y: word ); external; +procedure mxPutImage; external; +procedure mxPutPixel( X, Y: word; C: byte ); external; +procedure mxPutTile; external; +procedure mxReadPlane( Plane: byte ); external; +procedure mxRotatePalette; external; +procedure mxRowAddress( RowAddress: byte ); external; +function mxSetClip( Clip: boolean ): boolean; external; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external; +procedure mxSetColor( Index, R, G, B: word ); external; +procedure mxSetFont( Font: pointer; Width, Height: word ); external; +procedure mxSetMode( Mode: word ); external; +procedure mxSetPalette( Palette: pointer; Start, Count: word ); external; +procedure mxSetTextColor( Color, Op: word ); external; +procedure mxSetTextStep( DeltaX, DeltaY: integer ); external; +procedure mxSetVirtualScreen( Width, Height: word ); external; +procedure mxSplitScreen( Line: word ); external; +procedure mxStartAddress( StartAddress: word ); external; +procedure mxStartLine; external; +procedure mxStretchImage; external; +procedure mxTerm; external; +procedure mxTransPutTile; external; +procedure mxWaitDisplay; external; +procedure mxWaitRetrace; external; +procedure mxWriteMode( Mode: byte ); external; +procedure mxWritePlane( Plane: byte ); external; + +procedure mxFillPoly; external; +procedure mxGouraudPoly; external; +procedure mxTexturePoly; external; +{$L MXPB} +{$L MXPF} +{$L MXPG} +{$L MXPT} + +{$L MXBB} +{$L MXCC} +{$L MXCG} +{$L MXCL} +{$L MXCR} +{$L MXFB} +{$L MXFP} +{$L MXGI} +{$L MXGM} +{$L MXGP} +{$L MXGV} +{$L MXHL} +{$L MXIT} +{$L MXLN} +{$L MXOT} +{$L MXPI} +{$L MXPN} +{$L MXPP} +{$L MXRA} +{$L MXRP} +{$L MXSA} +{$L MXSC} +{$L MXSI} +{$L MXSL} +{$L MXSM} +{$L MXSP} +{$L MXSS} +{$L MXTL} +{$L MXVS} +{$L MXWD} +{$L MXWM} +{$L MXWP} +{$L MXWR} + +(* + Prints a Turbo Pascal string. + Note: BP 7.0 supports ASCIIZ strings (PChar type). +*) +procedure mxOutStr; +begin + S := S + #0; + mxOutText( X, Y, @S[1] ); +end; + +end. diff --git a/16/x_/modex/DEMO01.EXE b/16/x_/modex/DEMO01.EXE new file mode 100755 index 00000000..28caff88 Binary files /dev/null and b/16/x_/modex/DEMO01.EXE differ diff --git a/16/x_/modex/DEMO01.PAS b/16/x_/modex/DEMO01.PAS new file mode 100755 index 00000000..c684acdd --- /dev/null +++ b/16/x_/modex/DEMO01.PAS @@ -0,0 +1,126 @@ +(* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + MAX_SPRITE = 100; +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO02.EXE b/16/x_/modex/DEMO02.EXE new file mode 100755 index 00000000..14e7dc72 Binary files /dev/null and b/16/x_/modex/DEMO02.EXE differ diff --git a/16/x_/modex/DEMO02.PAS b/16/x_/modex/DEMO02.PAS new file mode 100755 index 00000000..6b4fb6f9 --- /dev/null +++ b/16/x_/modex/DEMO02.PAS @@ -0,0 +1,125 @@ +(* + DEMO02 - Texture mapping and palette rotation + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Plasma, Threed; + +const + LSIZE = 85; + Trans : TPoint = ( X:0; Y:0; Z:0 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of T2DPoint; + Width : word; + Data : array[ 1..64*64 ] of byte; + end; + TQuad = record + VtxCnt : word; + Vtx : array[ 0..3 ] of word; + Texture: word; + end; +var + Vtx : array[ 0..7 ] of TPoint; + XVtx : array[ 0..7 ] of TPoint; + VVtx : array[ 0..7 ] of T2DPoint; + Face : array[ 0..5 ] of TQuad; + Txts : array[ 0..5 ] of TTexture; + Nrm : array[ 0..5 ] of TPoint; + XNrm : array[ 0..5 ] of TPoint; + Page : word; + Palette: array[ byte ] of record R, G, B: byte; end; + +(* Make a 64x64 plasma to be used as texture *) +procedure MakeTexture( Idx: word ); +var + I: word; +begin + mxFillBox( 0, 0, 64, 64, 0, OP_SET ); + MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 ); + mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 ); + (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *) + with Txts[Idx] do begin + Desc[0].X := $80; Desc[0].Y := $80; + Desc[1].X := $80; Desc[1].Y := $3F80; + Desc[2].X := $3F80; Desc[2].Y := $3F80; + Desc[3].X := $3F80; Desc[3].Y := $80; + Width := 64; + end; +end; + +procedure Init; +var + I: integer; +begin + (* Build vertexes for a cube *) + with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + for I:=0 to 7 do begin (* Make points 16:16 fixed *) + Vtx[I].X := Vtx[I].X*$10000; + Vtx[I].Y := Vtx[I].Y*$10000; + Vtx[I].Z := Vtx[I].Z*$10000; + end; + (* Build faces *) + with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end; + with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end; + with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end; + with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end; + with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end; + with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end; + for I:=0 to 5 do Face[I].Texture := I; + (* Build textures and palette *) + Randomize; + FillChar( Palette, SizeOf(Palette), 0 ); + MakePlasmaPalette( Palette, PAL_RGB ); + mxSetPalette( @Palette, 0, 193 ); + for I:=0 to 5 do MakeTexture( I ); +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, 8 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + mxRotatePalette( @Palette[1], 192, 3 ); (* Rotate palette *) + (* Draw cube: backface culling is straighforward in this case, so *) + (* it can be handled by the polygon filling procedure *) + for I:=0 to 5 do + mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width ); + mxStartLine( Page ); (* Flip pages *) + mxSetPalette( @Palette[1], 1, 192 ); (* Set new palette *) + Page := 240-Page; + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO03.EXE b/16/x_/modex/DEMO03.EXE new file mode 100755 index 00000000..c646c4b0 Binary files /dev/null and b/16/x_/modex/DEMO03.EXE differ diff --git a/16/x_/modex/DEMO03.PAS b/16/x_/modex/DEMO03.PAS new file mode 100755 index 00000000..01d10f49 --- /dev/null +++ b/16/x_/modex/DEMO03.PAS @@ -0,0 +1,152 @@ +(* + DEMO03 - Simple star animation, morphs between a cube and a sphere + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 1000; (* Number of points *) + EDGE = 70; (* Length of cube edge *) + RADIUS = 90; (* Radius of sphere *) + WAITCOUNT = 192; (* Frames to wait for non-morphing shapes *) + MS = 32; (* Number of steps for morphing *) + Trans : TPoint = ( X:0; Y:0; Z:0 ); + InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 ); + InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS ); + InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 ); + InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 ); +type + T2DPoint = record + X, Y: integer; + end; + T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint; + P3DPointArray = ^T3DPointArray; +var + CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray; + VVtx : array[ 0..MAXVTX-1 ] of T2DPoint; + Page : word; + Status, Count, Delta1, Delta2, Morph1, Morph2: integer; + +procedure Swap( var A, B: longint ); +var + L: longint; +begin + L := A; A := B; B := L; +end; + +function Toggle( A: longint ): longint; +begin + Toggle := A; + if( Random(2) = 0 ) then Toggle := -A; +end; + +procedure Init; +label Retry; +var + I: integer; +begin + New( CubeVtx ); + New( SphereVtx ); + New( Vtx ); + New( XVtx ); + (* Build vertexes (yes, I know this piece of code is terrible) *) + Randomize; + for I:=0 to MAXVTX-1 do begin + with CubeVtx^[I] do begin + (* Build cube *) + X := (longint(Random(2*EDGE))-EDGE)*$10000; + Y := (longint(Random(2*EDGE))-EDGE)*$10000; + Z := Toggle( EDGE*$10000 ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + end; + with SphereVtx^[I] do begin + (* Build sphere *) +Retry: + X := (longint(Random(2*RADIUS))-RADIUS); + Y := (longint(Random(2*RADIUS))-RADIUS); + if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry; + Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + X := X * $10000; Y := Y * $10000; Z := Z * $10000; + end; + end; + (* Initialize morphing *) + Move( CubeVtx^, Vtx^, SizeOf(Vtx^) ); + Status := 0; + Count := WAITCOUNT; +end; + +procedure Morph; +var + I: integer; +begin + (* Fully unoptimized, slowest loop I could think of! *) + for I:=0 to MAXVTX-1 do begin + Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS; + Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS; + Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS; + end; +end; + +var + AX, AY, AZ: byte; + I: word; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + C := #0; + repeat + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx^, XVtx^, MAXVTX ); (* 3D transform points *) + tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw points *) + for I:=0 to MAXVTX-1 do + mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 ); + mxStartLine( Page ); (* Flip pages *) + Page := 240-Page; + (* Morph *) + if( Odd(Status) ) then begin + Morph; + Inc( Morph1, Delta1 ); + Inc( Morph2, Delta2 ); + if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status ); + if( Status = 4 ) then Status := 0; + end + else begin + Dec( Count ); + if( Count < 0 ) then begin + Inc( Status ); + Count := WAITCOUNT; + Morph1 := InitMorph1[Status]; + Morph2 := InitMorph2[Status]; + Delta1 := InitDelta1[Status]; + Delta2 := InitDelta2[Status]; + end; + end; + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO04.DAT b/16/x_/modex/DEMO04.DAT new file mode 100755 index 00000000..72aaad08 Binary files /dev/null and b/16/x_/modex/DEMO04.DAT differ diff --git a/16/x_/modex/DEMO04.EXE b/16/x_/modex/DEMO04.EXE new file mode 100755 index 00000000..1fec5e8a Binary files /dev/null and b/16/x_/modex/DEMO04.EXE differ diff --git a/16/x_/modex/DEMO04.PAS b/16/x_/modex/DEMO04.PAS new file mode 100755 index 00000000..1a946315 --- /dev/null +++ b/16/x_/modex/DEMO04.PAS @@ -0,0 +1,198 @@ +(* + DEMO04 - Multiple textures and triple buffering (3 pages) + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 256; + MAXCUB = 2; + MAXTXT = 2; + Trans : TPoint = ( X:0; Y:0; Z:0 ); + TxtSunDial: array[ 0..7 ] of word = ( + $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 ); + TxtSapphire : array[ 0..7 ] of word = ( + $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 ); + TxtMarble: array[ 0..7 ] of word = ( + $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of record X, Y: word end; + Width : word; + Data : pointer; + end; + TQuad = record + Vtx : array[ 0..3 ] of word; + Texture: word; + end; + TCube = record + Face : array[ 0..5 ] of TQuad; + Base : integer; + end; +var + Vtx, XVtx: array[ 0..MAXVTX ] of TPoint; + VVtx : array[ 0..MAXVTX ] of T2DPoint; + Cube : array[ 0..MAXCUB ] of TCube; + ZList : array[ 0..MAXCUB ] of integer; + VtxCnt : word; + Txts : array[ 0..MAXTXT ] of TTexture; + Page : word; + Palette : array[ byte ] of record R, G, B: byte; end; + TxtDat1, TxtDat2: pointer; + +(* Add a new entry to the vertex array *) +procedure AddVtx( PX, PY, PZ: longint ); +begin + with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end; + Inc( VtxCnt ); +end; + +procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer ); +const + FaceIdx: array[ 0..23 ] of integer = ( + 0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 ); +var + I, VC: integer; +begin + VC := VtxCnt; + C.Base := VC; + AddVtx( X1+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y2+TY, Z2+TZ ); + AddVtx( X1+TX, Y2+TY, Z2+TZ ); + for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I]; + for I:=0 to 5 do C.Face[I].Texture := Texture; +end; + +procedure MakeTexture( Idx: integer; var VtxData ); +var + P: ^word; + I: integer; +begin + P := @VtxData; + with Txts[Idx] do begin + for I:=0 to 3 do begin + Desc[I].X := P^; Inc( P ); + Desc[I].Y := P^; Inc( P ); + end; + Width := 129; + Data := TxtDat1; + end; +end; + +procedure Init; +var + I: integer; + V: integer; + F: file; + P: array[ 1..768 ] of byte; +begin + (* Initialize objects *) + VtxCnt := 0; + MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 ); (* Sundial *) + Cube[0].Face[0].Texture := 0; + V := VtxCnt; + MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *) + tdSetTranslation( Trans ); + tdSetRotation( 32, 32, 00 ); + tdRotate( Vtx[V], XVtx[V], 8 ); (* Got to rotate this cube *) + for I:=V to V+7 do begin + Vtx[I].X := XVtx[I].X; + Vtx[I].Y := XVtx[I].Y; + Vtx[I].Z := XVtx[I].Z + 100*$10000; + end; + MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *) + (* Load texture and palette *) + Assign( F, 'DEMO04.DAT' ); + Reset( F, 1 ); + BlockRead( F, P, SizeOf(P) ); + mxSetPalette( @P, 0, 256 ); + GetMem( TxtDat1, 63*1024 ); + BlockRead( F, TxtDat1^, 129*286 ); + Close( F ); + TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 ); + (* Init textures *) + MakeTexture( 0, TxtSundial ); + MakeTexture( 1, TxtMarble ); + MakeTexture( 2, TxtSapphire ); + Txts[2].Data := TxtDat2; +end; + +(* Sort procedure, not worth optimizing with only a few objects *) +procedure SortObjects; +var + I, J, K: integer; + ZMax: array[ 0..MAXCUB ] of longint; + ZI: integer; + L: longint; +begin + for I:=0 to MAXCUB do begin + L := XVtx[Cube[I].Base].Z; + for J:=1 to 7 do + if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z; + ZMax[I] := L; + ZList[I] := I; + end; + for I:=0 to MAXCUB-1 do begin + ZI := I; + for J:=I+1 to MAXCUB do + if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J; + if( ZI <> I ) then begin + K := ZList[I]; + ZList[I] := ZList[ZI]; + ZList[ZI] := K; + end; + end; +end; + +var + AX, AY, AZ: byte; + I, J, K: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + (* Init 3D transforms, perspective is intentionally exaggerated *) + AX := 0; AY := 0; AZ := 0; + tdSetTranslation( Trans ); + tdSetPerspective( 600*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, VtxCnt ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 1 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw objects *) + SortObjects; + for I:=0 to MAXCUB do with Cube[ZList[I]] do begin + for J:=0 to 5 do begin + K := Face[J].Texture; + mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width ); + end; + end; + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* If the frame rate seems low, try to remove this line *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO05.EXE b/16/x_/modex/DEMO05.EXE new file mode 100755 index 00000000..21a7c207 Binary files /dev/null and b/16/x_/modex/DEMO05.EXE differ diff --git a/16/x_/modex/DEMO05.PAS b/16/x_/modex/DEMO05.PAS new file mode 100755 index 00000000..819c5cf3 --- /dev/null +++ b/16/x_/modex/DEMO05.PAS @@ -0,0 +1,131 @@ +(* + DEMO05 - A Gouraud-shaded rotating torus + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex, Threed; + +(* Define ALTPAL for alternate palette *) +{$define ALTPAL} + +const + MAXVTX1 = 15; RADIUS1 = 70; (* MAXVTX1+1 must be multiple of 4 *) + MAXVTX2 = 15; RADIUS2 = 30; + MAXVTX = (MAXVTX1+1)*(MAXVTX2+1)-1; + MAXFACE = MAXVTX; + Trans : TPoint = ( X:0; Y:0; Z:0 ); (* Object translation *) + Light : TPoint = ( X:0; Y:0; Z:-63*$10000 ); (* Light direction *) +type + TQuad = record + QVtx : array[ 0..3 ] of integer; + end; +var + Vtx, XVtx : array[ 0..MAXVTX ] of TPoint; (* Points *) + VVtx : array[ 0..MAXVTX ] of record X, Y: integer end; + Face : array[ 0..MAXFACE ] of TQuad; (* Polys *) + Culled : array[ 0..MAXFACE ] of integer; + GNrm,XGNrm: array[ 0..MAXVTX ] of TVector; (* Gouraud normals *) + VtxLight : array[ 0..MAXVTX ] of integer; (* Points brightness *) + Page : word; + +function GetVtx( I1, I2: integer ): integer; +begin + GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1); +end; + +procedure Init; +var + R, N, X, Y, Z: real; + I, J, K, V: integer; +begin + (* Build vertexes *) + for I:=0 to MAXVTX1 do begin + K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1); + R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) ); + for J:=0 to MAXVTX2 do begin + V := I*(MAXVTX2+1)+J; (* Index of current vertex *) + (* Compute coordinates of current vertex *) + X := R*Cos(2*J*Pi / (MAXVTX2+1)); (* Get coordinates *) + Y := R*Sin(2*J*Pi / (MAXVTX2+1)); + Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1)); + Vtx[V].X := Round( X )*$10000; (* Save coordinates *) + Vtx[V].Y := Round( Y )*$10000; + Vtx[V].Z := Round( Z )*$10000; + (* Compute direction of Gouraud normal thru current vertex *) + X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1)); + Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1)); + N := Sqrt( X*X + Y*Y + Z*Z ); (* Get vector length *) + GNrm[V].X := Trunc( X*$10000/N ); (* Save normal vector *) + GNrm[V].Y := Trunc( Y*$10000/N ); + GNrm[V].Z := Trunc( Z*$10000/N ); + end; + end; + (* Generate faces so that depth-sorting is not needed: there are still *) + (* some *very* little errors, but this is the best I could devise *) + J := 0; + K := 0; + for I:=0 to MAXFACE do with Face[I] do begin + QVtx[0] := GetVtx( J, K ); + QVtx[1] := GetVtx( J, K+1 ); + QVtx[2] := GetVtx( J+1, K+1 ); + QVtx[3] := GetVtx( J+1, K ); + Inc( K ); + if( K > MAXVTX2 ) then begin + K := 0; + Inc( J ); + end; + end; +{$ifndef ALTPAL} + for I:=0 to 63 do mxSetColor( I+64, 0, 0, I ); (* Blue palette *) +{$else} + for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *) + for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 ); +{$endif} +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetLight( Light ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, MAXVTX+1 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page ); + tdRotate( GNrm, XGNrm, MAXVTX+1 ); (* Rotate Gouraud normals *) + tdTransformLight( XGNrm, VtxLight, MAXVTX+1 ); + (* Backplane culling is not really needed here! *) + FillChar( Culled, SizeOf(Culled), 0 ); + tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 3 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw polygons *) + for I:=0 to MAXFACE do with Face[I] do + if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 ); + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* Uncomment this instruction if screen flickers *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO06.DAT b/16/x_/modex/DEMO06.DAT new file mode 100755 index 00000000..1ac2c2bb Binary files /dev/null and b/16/x_/modex/DEMO06.DAT differ diff --git a/16/x_/modex/DEMO06.EXE b/16/x_/modex/DEMO06.EXE new file mode 100755 index 00000000..f1308e8a Binary files /dev/null and b/16/x_/modex/DEMO06.EXE differ diff --git a/16/x_/modex/DEMO06.PAS b/16/x_/modex/DEMO06.PAS new file mode 100755 index 00000000..f26af067 --- /dev/null +++ b/16/x_/modex/DEMO06.PAS @@ -0,0 +1,135 @@ +(* + DEMO06 - Magnifying glass + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + R = 40; (* Lens radius *) + K : real = 1.8; (* Magnifying factor, less makes a stronger lens *) +type + TLine = array[ 0..319 ] of byte; + PLine = ^TLine; + TScreen = array[ 0..239 ] of PLine; +var + VScreen: TScreen; (* Virtual screen *) + BallX : array[ 0..R, 0..R ] of integer; + BallY : array[ 0..R, 0..R ] of integer; + Sprite : array[ -R..R, -R..R ] of byte; + Page : word; + +(* Returns "lens-view" coordinates of X,Y *) +procedure GetCoords( var X, Y: integer ); +var + LR, Z, SinA, SinB, TgB, Q: real; +begin + LR := Sqrt( X*X + Y*Y ); + if( LR = 0 ) then Exit; + if( LR < R ) then begin + Z := Sqrt( R*R - LR*LR ); + SinA := LR / R; + SinB := SinA / K; + TgB := SinB / Sqrt( 1-SinB*SinB ); + Q := LR - TgB*Z; + X := Round( X * ( Q/LR ) ); + Y := Round( Y * ( Q/LR ) ); + end; +end; + +procedure Init; +var + F : file; + Palette: array[ 0..767 ] of record R, G, B: byte; end; + X, Y, + X2, Y2 : integer; +begin + (* Load background image *) + Assign( F, 'demo06.dat' ); + Reset( F, 1 ); + BlockRead( F, Palette, 768 ); + mxSetPalette( @Palette, 0, 256 ); + for Y:=0 to 239 do begin + New( VScreen[Y] ); + BlockRead( F, VScreen[Y]^, 320 ); + mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE ); + end; + Close( F ); + (* Build lens *) + for X:=0 to R do begin + for Y:=0 to R do begin + X2 := X; + Y2 := Y; + GetCoords( X2, Y2 ); + BallX[X, Y] := X2; + BallY[X, Y] := Y2; + end; + end; +end; + +procedure PutLens( OX, OY: integer ); +var + X, Y: integer; +begin + for X:=0 to R do begin + for Y:=0 to R do begin + Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + end; + end; + (* Draw the sprite *) + mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE ); +end; + +function Delta: integer; +begin + Delta := Random(3)+2; +end; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*Delta; + end; +end; + +var + X, Y, DX, DY: integer; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; + X := R; + Y := R; + Randomize; + DX := Delta; + DY := Delta; + + (* Main loop *) + repeat + (* Update video *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + PutLens( X, Y ); + mxCircle( X, Page+Y, R, 0 ); + (* Update lens coordinates *) + Inc( X, DX ); + Check( X+R >= 319, X, DX, 319-R, -1 ); + Check( X <= R, X, DX, R, +1 ); + Inc( Y, DY ); + Check( Y+R >= 239, Y, DY, 239-R, -1 ); + Check( Y <= R, Y, DY, R, +1 ); + (* Flip pages: double buffering, avoid wait for display *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 0; end; + end; + mxWaitRetrace; (* Wait for hidden page to show *) + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/DEMO07.EXE b/16/x_/modex/DEMO07.EXE new file mode 100755 index 00000000..8a401169 Binary files /dev/null and b/16/x_/modex/DEMO07.EXE differ diff --git a/16/x_/modex/DEMO07.PAS b/16/x_/modex/DEMO07.PAS new file mode 100755 index 00000000..04fff790 --- /dev/null +++ b/16/x_/modex/DEMO07.PAS @@ -0,0 +1,68 @@ +(* + DEMO07 - Hardware scrolling + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + (* Change this if scrolling seems jerky (this simple program does *) + (* not handle vertical retrace/display very well) *) + STEPS = 5; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*(Random(3)+2); + end; +end; + +var + I, X, Y, DX, DY: integer; +begin + (* Initialize library and graphics mode *) + mxInit; + mxSetMode( MX_320x200 ); + (* Set a 640x400 virtual screen *) + mxSetVirtualScreen( 640, 400 ); + mxSetClip( TRUE ); + + X := 0; + Y := 0; + DX := 1; + DY := 1; + + (* Main loop: draw lines, circles, points and rectangles in separate *) + (* 320x200 windows, while smoothly panning virtual screen *) + while( not KeyPressed ) do begin + (* Points *) + mxSetClipRegion( 0, 0, 320, 200 ); + for I:=1 to STEPS do + mxPutPixel( Random(320), Random(200), Random(16) ); + (* Lines *) + mxSetClipRegion( 0, 200, 320, 200 ); + for I:=1 to STEPS do + mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET ); + (* Circles *) + mxSetClipRegion( 320, 0, 320, 200 ); + for I:=1 to STEPS do + mxCircle( Random(320)+320, Random(200), Random(100), Random(16) ); + (* Boxes *) + mxSetClipRegion( 320, 200, 320, 200 ); + for I:=1 to STEPS do + mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET ); + (* Pan *) + Inc( X, DX ); + Check( X+320 >= 639, X, DX, 319, -1 ); + Check( X < 0, X, DX, 0, +1 ); + Inc( Y, DY ); + Check( Y+200 >= 399, Y, DY, 199, -1 ); + Check( Y < 0, Y, DY, 0, +1 ); + mxPan( X, Y ); + mxWaitRetrace; + end; + + (* Shutdown *) + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/MATH.INC b/16/x_/modex/MATH.INC new file mode 100755 index 00000000..742af410 --- /dev/null +++ b/16/x_/modex/MATH.INC @@ -0,0 +1,34 @@ +; +; MATH.INC - Include file for THREED.ASM +; + +; 3-dimensional point, coordinates in fixed format (16:16) +; +TPOINT STRUC + X DD ? + Y DD ? + Z DD ? +TPOINT ENDS + +; 2-dimensional point, coordinates in integer format +; +TIMAGEPOINT STRUC + IX DW ? + IY DW ? +TIMAGEPOINT ENDS + +; Fixed-point divide: EAX = EAX / arg +; +.xdiv MACRO arg + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv arg +ENDM + +; Fixed-point multiply: EAX = EAX * arg +; +.xmul MACRO arg + imul arg + shrd eax, edx, 16 +ENDM diff --git a/16/x_/modex/PLASMA.PAS b/16/x_/modex/PLASMA.PAS new file mode 100755 index 00000000..237e292a --- /dev/null +++ b/16/x_/modex/PLASMA.PAS @@ -0,0 +1,103 @@ +unit Plasma; +interface + +const + PAL_RGB = 0; + PAL_CLOUDS = 1; + PAL_LANDSCAPE = 2; + +procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte ); +procedure MakePlasmaPalette( var Palette; What: word ); + +implementation uses Modex; + +procedure NewColor( XA, YA, X, Y, XB, YB: integer ); +var + Color: longint; +begin + Color := Abs( XA-XB )+Abs( YA-YB ); + Color := Random( Color shl 1 )-Color; + Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1; + if( Color < 1 ) then Color := 1; + if( Color > 192 ) then Color := 192; + if( mxGetPixel( X, Y ) = 0 ) then + mxPutPixel( X, Y, Lo(Color) ); +end; + +procedure Divide( X1, Y1, X2, Y2: integer ); +var + X, Y, Color: integer; +begin + if not( (X2-X1<2)and(Y2-Y1<2) ) then begin + X := (X1+X2) shr 1; + Y := (Y1+Y2) shr 1; + NewColor( X1, Y1, X, Y1, X2, Y1 ); + NewColor( X2, Y1, X2, Y, X2, Y2 ); + NewColor( X1, Y2, X, Y2, X2, Y2 ); + NewColor( X1, Y1, X1, Y, X1, Y2 ); + Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+ + mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2; + mxPutPixel( X, Y, Color ); + Divide( X1, Y1, X, Y ); + Divide( X, Y1, X2, Y ); + Divide( X, Y, X2, Y2 ); + Divide( X1, Y, X, Y2 ); + end; +end; + +procedure MakePlasma; +begin + Dec( W ); + Dec( H ); + mxPutPixel( X, Y, C1 ); + mxPutPixel( X, Y+H, C2 ); + mxPutPixel( X+W, Y+H, C3 ); + mxPutPixel( X+W, Y, C4 ); + Divide( X, Y, X+W, Y+H ); +end; + +procedure MakePlasmaPalette; +type + TPal = array[ byte ] of record R, G, B: byte end; +var + I: word; +begin + FillChar( TPal(Palette)[1], 192*3, 0 ); + case What of + PAL_CLOUDS: + for I:=1 to 192 do begin + TPal(Palette)[I].R := Abs( I-96 )*63 div 96; + TPal(Palette)[I].G := Abs( I-96 )*63 div 96; + TPal(Palette)[I].B := 63; + end; + PAL_LANDSCAPE: + begin + for I:=0 to 31 do begin + TPal(Palette)[I+1].R := I; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := I + I shr 1+15; + end; + for I:=32 to 63 do begin + TPal(Palette)[I+1].R := 0; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := 0; + end; + for I:=64 to 191 do begin + TPal(Palette)[I+1].R := (I-64) div 3 + 15; + TPal(Palette)[I+1].G := (I-64) div 3 + 15; + TPal(Palette)[I+1].B := (I-64) div 3 + 15; + end; + end; + else + for I:=1 to 64 do begin + TPal(Palette)[I].G := I-1; + TPal(Palette)[I].B := 64-I; + TPal(Palette)[I+64].R := I-1; + TPal(Palette)[I+64].G := 64-I; + TPal(Palette)[I+128].B := I-1; + TPal(Palette)[I+128].R := 64-I; + end; + end; +end; + +end. \ No newline at end of file diff --git a/16/x_/modex/QIX2.EXE b/16/x_/modex/QIX2.EXE new file mode 100755 index 00000000..a10d7db5 Binary files /dev/null and b/16/x_/modex/QIX2.EXE differ diff --git a/16/x_/modex/QIX2.PAS b/16/x_/modex/QIX2.PAS new file mode 100755 index 00000000..d1b59791 --- /dev/null +++ b/16/x_/modex/QIX2.PAS @@ -0,0 +1,210 @@ +{$E-,N+} +uses Crt, Modex; + +const + DEFVERT = 12; (* Vertex count *) + DEFREPL = 3; (* Repetition count *) + DEFQIXS = 2; (* Qixs *) + FADESPEED = 48; +type + TPoint = record + X, Y : integer; + end; + TRGB = record + R, G, B: byte; + end; + TQix = record + Color: integer; + Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint; + Delta: array[ 0..DEFVERT-1 ] of TPoint; + end; +var + Page : integer; + MaxX, + MaxY : word; + Qix : array[ 0..DEFQIXS-1 ] of TQix; + Pal : array[ byte ] of TRGB; + +type + TReal = double; + TRPoint = record + X, Y: TReal; + end; + TMatrix = array[ 0..3, 0..3 ] of TReal; +var + M: TMatrix; + G: array[ 0..DEFVERT-1 ] of TRPoint; + C: array[ 0..DEFVERT-1 ] of TRPoint; + +procedure BumpPal( Idx, DR, DG, DB, Steps: integer ); +var + I: integer; +begin + for I:=1 to Steps do begin + Pal[Idx+1].R := Pal[Idx].R + DR; + Pal[Idx+1].G := Pal[Idx].G + DG; + Pal[Idx+1].B := Pal[Idx].B + DB; + Inc( Idx ); + end; +end; + +procedure InitPalette; +begin + with Pal[0] do begin R:=0; G:=0; B:=0; end; + with Pal[1] do begin R:=0; G:=0; B:=62; end; + BumpPal( 1, 0, 2, -2, 31 ); + BumpPal( 32, 2, -2, 0, 31 ); + BumpPal( 63, -2, 2, 2, 31 ); + BumpPal( 94, 2, 0, -2, 31 ); + BumpPal( 125, -2, -2, 2, 31 ); +end; + +procedure Init( var Qix: TQix; Color: integer ); +var + I: integer; +begin + FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 ); + for I:=0 to DEFVERT-1 do begin + Qix.Vert[I, DEFREPL-1].X := Random( MaxX ); + Qix.Vert[I, DEFREPL-1].Y := Random( MaxY ); + Qix.Delta[I].X := Random(5)+1; + Qix.Delta[I].Y := Random(5)+1; + end; + Qix.Color := Color; + + (* Initialize matrix (Catmull-Rom) *) + M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2; + M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2; + M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0; + M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0; +end; + +procedure mxBezier( var Qix: TQix; I0, Idx, N: integer ); +var + I, J: integer; + T, T2, T3: TReal; + X0, Y0, X, Y: TReal; + Delta: TReal; +begin + (* Compute coefficients *) + for I:=0 to 3 do begin + C[I].X := 0; + for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X; + C[I].Y := 0; + for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y; + end; + X0 := C[3].X; + Y0 := C[3].Y; + Delta := 1 / N; + T := 0; + for I:=1 to N do begin + T := T + Delta; + T2 := T*T; + T3 := T*T2; + X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X; + Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y; + mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET ); + X0 := X; + Y0 := Y; + end; +end; + +procedure Plot( var Qix: TQix; Idx: integer ); +var + I, J: integer; +begin + for I:=0 to DEFVERT-1 do begin + mxBezier( Qix, I, Idx, 12 ); + end; +end; + +procedure Update( var Qix: TQix; Idx: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Inc( Vert[I,Idx].X, Delta[I].X ); + if( Vert[I,Idx].X < 0 ) then begin + Vert[I,Idx].X := 0; + Delta[I].X := Random( 5 )+1; + end; + if( Vert[I,Idx].X > MaxX ) then begin + Vert[I,Idx].X := MaxX; + Delta[I].X := -Random( 5 )-1; + end; + Inc( Vert[I,Idx].Y, Delta[I].Y ); + if( Vert[I,Idx].Y < 0 ) then begin + Vert[I,Idx].Y := 0; + Delta[I].Y := Random( 5 )+1; + end; + if( Vert[I,Idx].Y > MaxY ) then begin + Vert[I,Idx].Y := MaxY; + Delta[I].Y := -Random( 5 )-1; + end; + end; +end; + +procedure Copy( var Qix: TQix; Dest, Src: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Vert[I,Dest].X := Vert[I,Src].X; + Vert[I,Dest].Y := Vert[I,Src].Y; + end; +end; + +procedure AnimateQix; +var + Q, Idx, I, J, P, Count: integer; +begin + Count := 0; + P := DEFREPL-1; + I := 0; + J := 1; + repeat + mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 ); + mxSetClip( TRUE ); + mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET ); + for Q:=0 to DEFQIXS-1 do begin + Copy( Qix[Q], I, P ); + Update( Qix[Q], I ); + for Idx:=0 to DEFREPL-1 do begin + Plot( Qix[Q], Idx ); + end; + end; + I := (I+1) mod DEFREPL; + J := (J+1) mod DEFREPL; + P := (P+1) mod DEFREPL; + Inc( Count ); + mxStartLine( Page ); + if( Count >= FADESPEED ) then begin + for Q:=0 to DEFQIXS-1 do begin + Inc( Qix[Q].Color ); + if( Qix[Q].Color > 156 ) then + Qix[Q].Color := 1; + end; + Count := 0; + end; + Page := 240-Page; + until( KeyPressed ); +end; + +var + I: integer; +begin + Randomize; + mxInit; + mxSetMode( MX_320x240 ); + mxGetScreenSize( MaxX, MaxY ); + for I:=0 to DEFQIXS-1 do + Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 ); + InitPalette; + mxSetPalette( @Pal, 0, 157 ); + Page := 240; + Dec( MaxX ); + Dec( MaxY ); + AnimateQix; + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/x_/modex/README.TXT b/16/x_/modex/README.TXT new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/x_/modex/README.TXT @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/x_/modex/SINCOS.INC b/16/x_/modex/SINCOS.INC new file mode 100755 index 00000000..6986eeeb --- /dev/null +++ b/16/x_/modex/SINCOS.INC @@ -0,0 +1,518 @@ +; +; SINCOS.INC - Sin/cos tables for THREED.ASM +; + +tblSin LABEL DWORD + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 +tblCos LABEL DWORD + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 diff --git a/16/x_/modex/THREED.ASM b/16/x_/modex/THREED.ASM new file mode 100755 index 00000000..5ecd3ba3 --- /dev/null +++ b/16/x_/modex/THREED.ASM @@ -0,0 +1,872 @@ +COMMENT / + Fixed-point math functions and 3D transforms + Copyright (c) 1993,94 by Alessandro Scotti +/ +WARN PRO +P386 +JUMPS +LOCALS + +INCLUDE MATH.INC + +PUBLIC tdFixedMul +PUBLIC tdGetNormal +PUBLIC tdRotate +PUBLIC tdGetSurfaceLight +PUBLIC tdSetLight +PUBLIC tdSetRotation +PUBLIC tdSetTranslation +PUBLIC tdTransform +PUBLIC tdTransformToImage +PUBLIC tdTransformLight +PUBLIC tdBackPlaneCull +PUBLIC tdSetPerspective + +;----------------------------------------------------------- +; +; Data segment +; +MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' + ASSUME ds:MATH_DATA + +INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table + +XRotation TPOINT <> ; 3x3 rotation matrix +YRotation TPOINT <> +ZRotation TPOINT <> + +Translation TPOINT <> ; Translation vector + +Light TPOINT <> ; Light vector +AmbientLight DW 00 ; Ambient light + +XScale DD 10000h ; Scaling factor for X coordinate +YScale DD 10000h ; Scaling factor for Y coordinate +PerspectiveDistance DD 20000000h + +MATH_DATA ENDS + +;----------------------------------------------------------- +; +; Code segment +; +MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING + +tdSetPerspective PROC PASCAL FAR + ARG Perspective:DWORD, \ + ScaleX:DWORD, \ + ScaleY:DWORD + USES ds + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov eax, [Perspective] + mov [PerspectiveDistance], eax + mov eax, [ScaleX] + mov [XScale], eax + mov eax, [ScaleY] + mov [YScale], eax + + ret +tdSetPerspective ENDP + + +;----------------------------------------------------------- +; +; Sets the rotation matrix. +; +; Input: +; RX = X-axis rotation angle +; RY = X-axis rotation angle +; RZ = X-axis rotation angle +; Output: +; none +; +tdSetRotation PROC PASCAL FAR + ARG RX:WORD, \ + RY:WORD, \ + RZ:WORD + USES ds, si, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov bx, [RZ] + mov si, [RY] + mov di, [RX] + shl bx, 2 + shl si, 2 + shl di, 2 + + push ebp ; We use EBP as a scratch register + +; Set X rotation + mov eax, tblCos[bx] + imul tblCos[si] + mov [XRotation.X], edx + + mov eax, tblSin[bx] + imul tblCos[si] + mov [XRotation.Y], edx + + mov eax, tblSin[si] + sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 + mov [XRotation.Z], eax + +; Set Y rotation + mov eax, tblCos[bx] + imul tblSin[si] ; EDX:EAX = fixed 16:48 + shrd eax, edx, 24 ; EAX = fixed 8:24 + imul tblSin[di] ; EDX:EAX = fixed 16:48 + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblCos[di] + add eax, ebp + adc edx, ecx ; EDX:EAX = fixed 16:48 + neg edx + mov [YRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblSin[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblCos[di] + sub eax, ebp + sbb edx, ecx + mov [YRotation.Y], edx + + mov eax, tblCos[si] + imul tblSin[di] + mov [YRotation.Z], edx + +; Set Z rotation + mov eax, tblCos[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblSin[di] + sub eax, ebp + sbb edx, ecx + mov [ZRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblSin[di] + add eax, ebp + add edx, ecx + neg edx + mov [ZRotation.Y], edx + + mov eax, tblCos[si] + imul tblCos[di] + mov [ZRotation.Z], edx + + pop ebp ; Restore EBP + + ret +tdSetRotation ENDP + +;----------------------------------------------------------- +; +; Sets the translation vector. +; +; Input: +; TV = pointer to translation vector +; Output: +; none +; +tdSetTranslation PROC PASCAL FAR + ARG TV:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [TV] + mov eax, es:[di].X + mov [Translation.X], eax + mov eax, es:[di].Y + mov [Translation.Y], eax + mov eax, es:[di].Z + mov [Translation.Z], eax + + ret +tdSetTranslation ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdTransform PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + LOCAL Adjust:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + + ALIGN DWORD +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + mov ebx, eax + shrd eax, edx, 16 + add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) + mov es:[di].Z, eax +; Get perspective factor + mov ebx, [PerspectiveDistance] + sub eax, ebx + neg eax ; EAX = PD - Z + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv ebx ; EAX = fixed 16:16 result + mov [Adjust], eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.X] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.Y] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdTransform ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT into an array of TIMAGEPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TIMAGEPOINT +; Count = number of entries to transform +; DeltaX = translation distance for the X coordinate +; DeltaY = translation distance for the Y coordinate +; Output: +; the maximum Z value +; +tdTransformToImage PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD + LOCAL Adjust:DWORD, \ + Max:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + mov [Max], 80000000h + +@@Loop: +; Check max Z + mov eax, fs:[si].Z + cmp eax, [Max] + jle @@1 + mov [Max], eax +@@1: + +; Transform X coordinate + mov ax, WORD PTR fs:[si].X[2] + add ax, [DeltaX] + mov es:[di].IX, ax + +; Transform Y coordinate + mov ax, WORD PTR fs:[si].Y[2] + add ax, [DeltaY] + mov es:[di].IY, ax + + add si, SIZE TPOINT + add di, SIZE TIMAGEPOINT + dec [Count] + jnz @@Loop + + mov eax, [Max] + shld edx, eax, 16 + ret +tdTransformToImage ENDP + +;----------------------------------------------------------- +; +; Sets the light source. +; +; Input: +; Light = pointer to light vector +; Output: +; none +; +tdSetLight PROC PASCAL FAR + ARG L:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [L] + mov eax, es:[di].X + mov [Light.X], eax + mov eax, es:[di].Y + mov [Light.Y], eax + mov eax, es:[di].Z + mov [Light.Z], eax + + ret +tdSetLight ENDP + +;----------------------------------------------------------- +; +; Computes light intensity for an array of surfaces. +; +; Input: +; Normals = pointer to an array of surface normals +; Lights = pointer to an array of integer to be filled with +; light intensity +; Count = number of elements to transform +; Output: +; none +; +tdTransformLight PROC PASCAL FAR + ARG Normals:DWORD, \ + Lights:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov fs, ax + ASSUME fs:MATH_DATA + + lds si, [Normals] + les di, [Lights] + ASSUME ds:NOTHING + +; Intensity is given by the dot product between the Light vector and +; the surface normal +@@Loop: + mov eax, ds:[si].Z + imul [Light.Z] + mov ebx, eax + mov ecx, edx + mov eax, ds:[si].Y + imul [Light.Y] + add ebx, eax + adc ecx, edx + mov eax, ds:[si].X + imul [Light.X] + add eax, ebx + adc edx, ecx ; EDX:EAX = fixed 32:32 intensity + add dx, [AmbientLight] + test dx, dx + jg @@1 + xor dx, dx ; Return 0 for no light +@@1: + mov es:[di], dx + inc di + inc di + add si, SIZE TPOINT + dec [Count] + jnz @@Loop + + ASSUME fs:NOTHING + ret +tdTransformLight ENDP + +;----------------------------------------------------------- +; +; Returns the light value given the normal to a surface. +; +; Input: +; Normal = pointer to TPOINT surface normal vector +; Output: +; AX = light intensity (>=0) +; Notes: +; the normal is rotated according to the current setting. +; +tdGetSurfaceLight PROC PASCAL FAR + ARG Normal:DWORD + USES ds, esi, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [Normal] + +; Transform Z coordinate + mov eax, es:[di].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.Z] + shrd eax, edx, 16 + mov esi, eax + +; Transform X coordinate + mov eax, es:[di].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add esi, eax + +; Transform Y coordinate + mov eax, es:[di].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add eax, esi + shr eax, 16 + +; Add ambient light + add ax, [AmbientLight] + test ax, ax + jge @@Exit + xor ax, ax + +@@Exit: + ret +tdGetSurfaceLight ENDP + +;----------------------------------------------------------- +; +; Rotates an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdRotate PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Z, eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdRotate ENDP + +tdFixedMul PROC PASCAL FAR + ARG F1:DWORD, \ + F2:DWORD + + mov eax, [F1] + imul [F2] + shr eax, 16 + + ret +tdFixedMul ENDP + +;----------------------------------------------------------- +; +; Returns in EAX the square root of EDX:EAX. +; +subSqrt PROC NEAR + push esi + push edi + + add eax, eax + adc edx, 0 + mov eax, edx ; Just discard the low bits + + mov esi, eax + xor edi, edi + shld edi, esi, 16 + shl esi, 16 +@@Loop: + mov ebx, eax + mul eax + add eax, esi + adc edx, edi + shrd eax, edx, 1 + shr edx, 1 + div ebx + cmp eax, ebx + jne @@Loop + +; Adjust EAX + shl eax, 8 + + pop edi + pop esi + ret +subSqrt ENDP + +;----------------------------------------------------------- +; +; Finds the unitary normal to a given surface. +; +; Input: +; Dest = pointer to TPOINT (vector) result +; P1, P2, P3 = pointer to TPOINT points on surface +; Output: +; none +; Notes: +; the normal is given by the cross-product between (P3-P1) and +; (P2-P1), so its orientation depends on the parameters order. +; +tdGetNormal PROC PASCAL FAR + ARG Dest:DWORD, \ + P1:DWORD, \ + P2:DWORD, \ + P3:DWORD + LOCAL V1:TPOINT, \ + V2:TPOINT, \ + N:TPOINT + USES ds, si, es, di + +; Get vector V1 + lds si, [P1] + les di, [P3] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V1.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V1.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V1.Z], eax + +; Get vector V2 + les di, [P2] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V2.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V2.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V2.Z], eax + +; Get normal vector (V1 x V2) + mov eax, [V1.Z] + imul [V2.Y] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Y] + imul [V2.Z] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.X], eax + + mov eax, [V1.X] + imul [V2.Z] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Z] + imul [V2.X] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Y], eax + + mov eax, [V1.Y] + imul [V2.X] + mov ebx, eax + mov ecx, edx + mov eax, [V1.X] + imul [V2.Y] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Z], eax + +; Get normal length + mov eax, [N.X] + imul eax + mov ebx, eax + mov ecx, edx + mov eax, [N.Y] + imul eax + add ebx, eax + adc ecx, edx + mov eax, [N.Z] + imul eax + add eax, ebx + adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z + call subSqrt ; EAX = normal length + mov ebx, eax + +; Adjust vector and save it + les di, [Dest] + mov eax, [N.X] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].X, eax + mov eax, [N.Y] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Y, eax + mov eax, [N.Z] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Z, eax + + ret +tdGetNormal ENDP + +TPOLY STRUC + Vtx DW 4 DUP(?) +TPOLY ENDS + +;----------------------------------------------------------- +; +; Performs surface removal on an array of polygons. +; +; Input: +; Poly = pointer to an array of TPOLY +; Vertex = pointer to an array of TPOINT +; Dest = pointer to an array of integer +; Count = number of polygons to check +; Step = size of TPOLY structure +; Output: +; if the n-th polygon is invisible the n-th entry of the +; Dest array is set to -1, other entries are not modified +; (so it's possible to use the Light array for Dest, because +; the light intensity is always >= 0) +; +tdBackPlaneCull PROC PASCAL FAR + ARG Step:WORD, \ + Poly:DWORD, \ + Vertex:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + ASSUME ds:NOTHING + + mov ds, WORD PTR Vertex[2] + les di, [Poly] + mov fs, WORD PTR Dest[2] + +@@Loop: + mov ax, es:[di].Vtx[2] ; Index of 2nd vertex + shl ax, 2 + mov bx, ax + shl ax, 1 + add bx, ax ; BX = index*SIZE TPOINT + add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex + mov ax, es:[di].Vtx[4] ; Index of 3rd vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex + mov ecx, ds:[si].X + sub ecx, ds:[bx].X ; ECX = V3.X-V2.X + mov edx, ds:[si].Y + sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y + mov ax, es:[di].Vtx[0] ; Index of 1st vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 1st vertex + mov eax, ds:[si].X + sub eax, ds:[bx].X ; EAX = V1.X-V2.X + mov esi, ds:[si].Y + sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y + imul edx + mov ebx, eax + xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) + mov eax, esi + imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) + sub eax, ebx + sbb edx, ecx + jl @@Next ; Polygon is visible + mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry + mov WORD PTR fs:[bx], -1 ; Remove polygon +@@Next: + add WORD PTR [Dest], 2 ; Next entry for dest + add di, [Step] ; Next polygon + dec [Count] + jnz @@Loop + + ret +tdBackPlaneCull ENDP + +MATH_TEXT ENDS +END diff --git a/16/x_/modex/THREED.H b/16/x_/modex/THREED.H new file mode 100755 index 00000000..b993ef86 --- /dev/null +++ b/16/x_/modex/THREED.H @@ -0,0 +1,32 @@ +typedef struct { + long x, y, z; +} TVECTOR; + +#define PVECTOR TVECTOR far * + +#define TPOINT TVECTOR +#define PPOINT PVECTOR + +#define VPTR void far * + +#ifdef __cplusplus +extern "C" { +#endif + +long far pascal tdFixedMul( long, long ); +int far pascal tdGetSurfaceLight( PPOINT ); +long far pascal tdTransformToImage( VPTR, VPTR, short, short, short ); + +void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short ); +void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT ); +void far pascal tdRotate( VPTR, VPTR, short ); +void far pascal tdSetLight( PVECTOR ); +void far pascal tdSetRotation( short, short, short ); +void far pascal tdSetTranslation( PVECTOR ); +void far pascal tdSetPerspective( long, long, long ); +void far pascal tdTransform( VPTR, VPTR, short ); +void far pascal tdTransformLight( VPTR, VPTR, short ); + +#ifdef __cplusplus +} +#endif diff --git a/16/x_/modex/THREED.PAS b/16/x_/modex/THREED.PAS new file mode 100755 index 00000000..8b712c9d --- /dev/null +++ b/16/x_/modex/THREED.PAS @@ -0,0 +1,40 @@ +unit ThreeD; +interface + +type + TVector = record + X, Y, Z : longint; + end; + TPoint = TVector; + +function tdFixedMul( F1, F2: longint ): longint; +function tdGetSurfaceLight( var Normal: TPoint ): integer; +function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint; + +procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word ); +procedure tdGetNormal( var Dest, P1, P2, P3: TVector ); +procedure tdRotate( var Source, Dest; Count: word ); +procedure tdSetLight( var Light: TVector ); +procedure tdSetRotation( RX, RY, RZ: word ); +procedure tdSetTranslation( var TV: TVector ); +procedure tdSetPerspective( PD, XF, YF: longint ); +procedure tdTransform( var Source, Dest; Count: word ); +procedure tdTransformLight( var Source, Dest; Count: word ); + +implementation + +function tdGetSurfaceLight; external; +procedure tdSetRotation( RX, RY, RZ: word ); external; +procedure tdGetNormal; external; +procedure tdSetTranslation( var TV: TVector ); external; +procedure tdTransform( var Source, Dest; Count: word ); external; +procedure tdRotate; external; +function tdTransformToImage; external; +procedure tdSetLight( var Light: TVector ); external; +procedure tdSetPerspective; external; +procedure tdTransformLight; external; +function tdFixedMul( F1, F2: longint ): longint; external; +procedure tdBackPlaneCull; external; +{$L THREED} + +end. diff --git a/16/x_/mxbb.asm b/16/x_/mxbb.asm new file mode 100755 index 00000000..ac6668ce --- /dev/null +++ b/16/x_/mxbb.asm @@ -0,0 +1,278 @@ +;----------------------------------------------------------- +; +; MXBB.ASM - Bit block transfer +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxBitBlt + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN subHorizontalLineInfo : NEAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves a block of video memory. +; +; Input: +; SX, SY = source coordinates +; Width = source width +; Height = source height +; DX, DY = destination coordinates +; Output: +; none +; +; Note: overlapping regions are not allowed. +; +mxBitBlt PROC FAR + ARG DestY:WORD, \ + DestX:WORD, \ + Height:WORD, \ + Width:WORD, \ + SY:WORD, \ + SX:WORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + SourceOffset:WORD, \ + DestOffset:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + WritePlane:BYTE, \ + LeftMask:BYTE, \ + RightMask:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + +; Exit now if null width + cmp [Width], 0 + je @@Exit + +; Calls the proper procedure to handle transfer + mov ax, [SX] + and al, 03h ; AL = source plane + mov dx, [DestX] + and dl, 03h ; DL = destination plane + mov bx, OFFSET subPlaneBlt + cmp al, dl ; Same source and destination plane? + jne @@BitBlt ; No, use slow procedure + mov bx, OFFSET subMoveBlt +@@BitBlt: + call bx + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; Uses write mode 1 for maximum speed. Only works if source +; and destination are plane-aligned. +; +subMoveBlt PROC NEAR +; Get horizontal line info and address of destination + mov bx, [DestX] + mov ax, [DestY] + mov cx, [Width] + call subHorizontalLineInfo + mov [LeftMask], al + mov [RightMask], ah + mov [Width], cx + +; Setup segments + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + +; Get address of source pixel + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + .shr si, 2 + add si, ax + +; Set write mode 1 + mov dx, GDC + mov ax, 4105h + out dx, ax + cld + +; Move left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] + .push si, di +@@L1: + movsb + add si, ax + add di, ax + dec cx + jnz @@L1 + .pop si, di + inc si + inc di + +; Move center block +@@C0: + mov bx, [Width] + test bx, bx + jz @@R0 + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov ax, [mx_BytesPerLine] + sub ax, bx + mov dx, [Height] + .push si, di +@@C1: + mov cx, bx ; CX = image width + rep movsb ; Cannot use "movsw" here! + add si, ax ; Next scan line + add di, ax ; Next scan line + dec dx ; All lines processed? + jnz @@C1 ; No, continue + .pop si, di + add si, bx + add di, bx + +; Move right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] +@@R1: + movsb + add si, ax + add di, ax + dec cx + jnz @@R1 + +@@Done: + mov dx, GDC + mov ax, 4005h + out dx, ax ; Restore write mode 0 + +@@Exit: + ret +subMoveBlt ENDP + +;----------------------------------------------------------- +; Moves one plane at a time. +; +subPlaneBlt PROC NEAR +; Compute extra bytes and width count for each plane + mov cx, [Width] + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Get pixel addresses + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + shr si, 1 + shr si, 1 + add si, ax ; DS:SI points to source + mov [SourceOffset], si + mov ax, [DestY] + mul [mx_BytesPerLine] + mov di, [DestX] + shr di, 1 + shr di, 1 + add di, ax ; ES:DI points to destination + mov [DestOffset], di + +; Adjust plane for output to VGA registers + mov ax, [SX] + and al, 03h + mov [ReadPlane], al + mov cx, [DestX] + and cl, 03h + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Ready to move now + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 + je @@Done + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov ax, [mx_BytesPerLine] + sub ax, ss:[bx] ; AX = extra bytes per line +@@Loop: + mov cx, ss:[bx] + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb + add si, ax + add di, ax + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + and [ReadPlane], 03h ; Should be faster on 386 using + jnz @@ReadPlaneOk ; BTR and ADC... + inc [SourceOffset] +@@ReadPlaneOk: + rol [WritePlane], 1 + adc [DestOffset], 0 + mov si, [SourceOffset] + mov di, [DestOffset] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Done: + ret +subPlaneBlt ENDP + +mxBitBlt ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxcc.asm b/16/x_/mxcc.asm new file mode 100755 index 00000000..4f78adb9 --- /dev/null +++ b/16/x_/mxcc.asm @@ -0,0 +1,644 @@ +;----------------------------------------------------------- +; +; MXCC.ASM - Fast clip line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC xsubClipLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblGroups LABEL WORD + DW 10, tbl00 + DW 10, tbl10 + DW 9, tbl20 + DW -1, 0 + DW 10, tbl40 + DW 10, tbl50 + DW 9, tbl60 + DW -1, 0 + DW 6, tbl80 + DW 6, tbl90 + DW 5, tblA0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 +tbl00 DW cc00, cc01, cc02, ccFF, cc04, cc05, cc06, ccFF, cc08, cc09, cc0A +tbl10 DW cc10, ccFF, cc12, ccFF, cc14, ccFF, cc16, ccFF, cc18, ccFF, cc1A +tbl20 DW cc20, cc21, ccFF, ccFF, cc24, cc25, ccFF, ccFF, cc28, cc29 +tbl40 DW cc40, cc41, cc42, ccFF, ccFF, ccFF, ccFF, ccFF, cc48, cc49, cc4A +tbl50 DW cc50, ccFF, cc52, ccFF, ccFF, ccFF, ccFF, ccFF, cc58, ccFF, cc5A +tbl60 DW cc60, cc61, ccFF, ccFF, ccFF, ccFF, ccFF, ccFF, cc68, cc69 +tbl80 DW cc80, cc81, cc82, ccFF, cc84, cc85, cc86 +tbl90 DW cc90, ccFF, cc92, ccFF, cc94, ccFF, cc96 +tblA0 DW ccA0, ccA1, ccFF, ccFF, ccA4, ccA5 + +ccTT: clc + ret +ccFF: stc + ret + +; Group 00 ------------------------------------------------- +; +cc00: + clc + ret +cc01: + jmp ClipQLeft +cc02: + jmp ClipQRight +cc04: + jmp ClipQTop +cc05: + call ClipQLeft + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc06: + call ClipQRight + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc08: + jmp ClipQBottom +cc09: + call ClipQLeft + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom +cc0A: + call ClipQRight + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom + +; Group 10 ------------------------------------------------- +; +cc10FF: + stc + ret +cc10TT: + clc + ret +cc10: + jmp ClipPLeft +cc12: + call ClipPLeft + jmp ClipQRight +cc14: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + jmp ClipQTop +cc16: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + call ClipQTop + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight +cc18: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + jmp ClipQBottom +cc1A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + call ClipQBottom + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight + +; Group 20 ------------------------------------------------- +; +cc20TT: + clc + ret +cc20FF: + stc + ret +cc20: + jmp ClipPRight +cc21: + call ClipPRight + jmp ClipQLeft +cc24: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + jmp ClipQTop +cc25: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + call ClipQTop + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft +cc28: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + jmp ClipQBottom +cc29: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + call ClipQBottom + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft + +; Group 40 ------------------------------------------------- +; +cc40TT: + clc + ret +cc40FF: + stc + ret +cc40: + jmp ClipPTop +cc41: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc40TT + jmp ClipQTop +cc42: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + jmp ClipQRight +cc48: + call ClipPTop + jmp ClipQBottom +cc49: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom +cc4A: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + call ClipQRight + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom + + +; Group 50 ------------------------------------------------- +; +cc50TT: + clc + ret +cc50FF: + stc + ret +cc50: + call ClipPLeft + cmp bx, [mx_ClipY1] + jge cc50TT + jmp ClipPTop +cc52: + call ClipQRight + cmp si, [mx_ClipY1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc58: + call ClipQBottom + cmp cx, [mx_ClipX1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc5A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc50FF + call ClipQRight + cmp bx, [mx_ClipY1] + jl cc50FF + cmp si, [mx_ClipY2] + jle cc50TT + jmp ClipQBottom + +; Group 60 ------------------------------------------------- +; +cc60TT: + clc + ret +cc60FF: + stc + ret +cc60: + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc61: + call ClipQLeft + cmp si, [mx_ClipY2] + jl cc60FF + call ClipPTop + cmp di, [mx_ClipX2] + jle cc60TT + jmp ClipPRight +cc68: + call ClipQBottom + cmp cx, [mx_ClipX2] + jg cc60FF + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc69: + call ClipQLeft + cmp si, [mx_ClipY1] + jl cc60FF + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc60FF + cmp si, [mx_ClipY2] + jle cc69_1 + call ClipQBottom +cc69_1: + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop + +; Group 80 ------------------------------------------------- +; +cc80TT: + clc + ret +cc80FF: + stc + ret +cc80: + jmp ClipPBottom +cc81: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + jmp ClipQLeft +cc82: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + jmp ClipQRight +cc84: + call ClipPBottom + jmp ClipQTop +cc85: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc80FF + jmp ClipQTop +cc86: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + call ClipQRight + cmp si, [mx_ClipY1] + jge cc80TT + jmp ClipQTop + +; Group 90 ------------------------------------------------- +; +cc90TT: + clc + ret +cc90FF: + stc + ret +cc90: + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc92: + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + call ClipPBottom + cmp di, [mx_ClipX1] + jge cc90TT + jmp ClipPLeft +cc94: + call ClipQTop + cmp cx, [mx_ClipX1] + jl cc90FF + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc96: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc90FF + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + cmp bx, [mx_ClipY2] + jle cc96_1 + call ClipPBottom +cc96_1: + cmp si, [mx_ClipY1] + jge cc90TT + jmp ClipQTop + +; Group A0 ------------------------------------------------- +; +ccA0TT: + clc + ret +ccA0FF: + stc + ret +ccA0: + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA1: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPBottom + cmp di, [mx_ClipX2] + jle ccA0TT + jmp ClipPRight +ccA4: + call ClipQTop + cmp cx, [mx_ClipX2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA5: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY1] + jl ccA0FF + cmp si, [mx_ClipY1] + jge ccA5_1 + call ClipQTop +ccA5_1: + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom + +; Y1 = (Y2-Y1)*(mx_ClipX1-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX1-DI)/(CX-DI)+BX +; X1 = mx_ClipX1 +ClipPLeft: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX1] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX1] + clc + ret + +; Y1 = (Y2-Y1)*(mx_ClipX2-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX2-DI)/(CX-DI)+BX +; X1 = mx_ClipX2 +ClipPRight: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX2] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY2-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY2-BX)/(SI-BX)+DI +; Y1 = mx_ClipY2 +ClipPBottom: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY2] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY1-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY1-BX)/(SI-BX)+DI +; Y1 = mx_ClipY1 +ClipPTop: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY1] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX1-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX1-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQLeft: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX1] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX2-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX2-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQRight: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX2] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY2-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY2-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQBottom: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY2] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY1-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY1-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQTop: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY1] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY1] + clc + ret + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses the Sobkow-Pospisil-Yang (SPY) algorithm: this was +; supposed to be twice as fast as Cohen-Sutherland, but my +; tests show only a very small increase in speed and a noticeable +; increase of the program size! Maybe this is caused by the +; slow speed of VGA cards, so probably a better test should +; be performed with lines drawn in RAM. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +xsubClipLine PROC NEAR + push bp + xor si, si ; SPY code + + cmp dx, [mx_ClipY2] + jle @@1 + or si, 08h + jmp @@2 +@@1: + cmp dx, [mx_ClipY1] + jge @@2 + or si, 04h +@@2: + + cmp cx, [mx_ClipX2] + jle @@3 + or si, 02h + jmp @@4 +@@3: + cmp cx, [mx_ClipX1] + jge @@4 + or si, 01h +@@4: + + cmp bx, [mx_ClipY2] + jle @@5 + or si, 80h + jmp @@6 +@@5: + cmp bx, [mx_ClipY1] + jge @@6 + or si, 40h +@@6: + + cmp ax, [mx_ClipX2] + jle @@7 + or si, 20h + jmp @@8 +@@7: + cmp ax, [mx_ClipX1] + jge @@8 + or si, 10h +@@8: + + mov di, si + and di, 000Fh ; Index of procedure + and si, 00F0h + .shr si, 2 ; Index of group (times 4) + cmp di, cs:tblGroups[si] ; Is index within range? + jg @@Exit ; No, line is full clipped + mov si, cs:tblGroups[si+2] ; Get offset of group table + shl di, 1 ; We must index word elements + add si, di ; Make full offset + mov di, ax ; Move X1 to DI and free AX + mov si, cs:[si] ; Get subroutine address + xchg dx, si ; Move Y2 to SI and free DX + call dx ; Call the proper subroutine + mov ax, di ; Restore AX to X1 + mov dx, si ; Restore DX to Y2 + pop bp + ret + +@@Exit: + pop bp + stc + ret +xsubClipLine ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxcg.asm b/16/x_/mxcg.asm new file mode 100755 index 00000000..42163d7a --- /dev/null +++ b/16/x_/mxcg.asm @@ -0,0 +1,69 @@ +;----------------------------------------------------------- +; +; MXCG.ASM - Color to gray conversion +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxColorToGray + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Converts RGB colors to gray shades. +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gray) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxColorToGray PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit + lds si, [SPal] + les di, [DPal] + cld +; We use the standard formula +; gray=(red*30 + green*59 + blue*11)/100 +; in the equivalent form +; gray=(red*77 + green*151 + blue*28)/256 +; which doesn't need the last divide. + mov bx, 77 SHL 8 + 151 +@@Loop: + lodsb ; Red + mul bh + mov dx, ax + lodsb ; Green + mul bl + add dx, ax + lodsb ; Blue + mov ah, 28 + mul ah + add ax, dx + mov al, ah + stosw ; Save new RGB + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxColorToGray ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxcl.asm b/16/x_/mxcl.asm new file mode 100755 index 00000000..aaa0bac3 --- /dev/null +++ b/16/x_/mxcl.asm @@ -0,0 +1,151 @@ +;----------------------------------------------------------- +; +; MXCL.ASM - Bresenham circle +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxCircle + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws a circle using the Bresenham algorithm. +; +; Input: +; XC, YC = center coordinates +; Radius = circle radius +; Color = circle color +; Output: +; none +; Note: +; computes only points in the first octant, all other +; points are obtained by symmetry. +; +mxCircle PROC FAR + ARG Color:BYTE:2, \ + Radius:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL Delta:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + xor si, si ; X + mov di, [Radius] ; Y + mov ax, 3 + sub ax, di + sub ax, di + mov [Delta], ax ; Delta = 3-R*2 + + mov ds, [mx_VideoSegment] + +@@Loop: + cmp si, di ; + jg @@Done ; Exit when X > Y +; Draw points + mov ax, si + mov bx, di + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + call @@subPutPixel + mov ax, si + mov bx, di + neg bx + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + neg bx + call @@subPutPixel + mov ax, di + mov bx, si + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + call @@subPutPixel + mov ax, di + mov bx, si + neg bx + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + neg bx + call @@subPutPixel +; Moves coordinates to next point + mov ax, [Delta] + test ax, ax + jl @@Next + mov ax, di + .shl ax, 2 + sub ax, 4 + sub [Delta], ax + dec di +@@Next: + mov ax, si + .shl ax, 2 + add ax, 6 + add [Delta], ax + inc si + jmp @@Loop + +@@Done: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;--------------------------------------- +; Put pixel function. +; Input: +; BX = X coordinate (relative to center) +; AX = Y coordinate (relative to center) +; DS = video segment +@@subPutPixel: + add bx, [XC] ; Get absolute coordinates + add ax, [YC] + + cmp bx, [mx_ClipX1] ; Clip pixel + jl @@subExit + cmp bx, [mx_ClipX2] + jg @@subExit + cmp ax, [mx_ClipY1] + jl @@subExit + cmp ax, [mx_ClipY2] + jg @@subExit + + mul [mx_BytesPerLine] ; Get pixel offset + mov cx, bx ; Save X coordinate + .shr bx, 2 + add bx, ax ; DS:BX = pixel offset + + and cl, 3 ; Set write plane + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[bx], al + +@@subExit: + retn +mxCircle ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxcr.asm b/16/x_/mxcr.asm new file mode 100755 index 00000000..ca1fa7bb --- /dev/null +++ b/16/x_/mxcr.asm @@ -0,0 +1,380 @@ +;----------------------------------------------------------- +; +; MXCR.ASM - Clip functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetSysClipRegion +PUBLIC mxGetClipRegion +PUBLIC mxSetClipRegion +PUBLIC mxSetClip +PUBLIC mxGetClip + +PUBLIC subClipBox +PUBLIC subClipImage + +PUBLIC mx_ClipX1 +PUBLIC mx_ClipY1 +PUBLIC mx_ClipX2 +PUBLIC mx_ClipY2 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD + +mx_ClipX1 DW ? ; Clip coordinates +mx_ClipY1 DW ? +mx_ClipX2 DW ? +mx_ClipY2 DW ? + +mx_SysClipX1 DW ? ; System clip coordinates +mx_SysClipY1 DW ? ; (active when mx_ClipStatus is FALSE) +mx_SysClipX2 DW ? +mx_SysClipY2 DW ? + +mx_UserClipX1 DW ? ; User clip coordinates +mx_UserClipY1 DW ? ; (active when mx_ClipStatus is TRUE) +mx_UserClipX2 DW ? +mx_UserClipY2 DW ? + +mx_ClipStatus DB ? + +;----------------------------------------------------------- +; +; Toggles clipping between user and system regions. +; +; Input: +; ClipStatus = TRUE (FALSE) to enable (disable) clipping +; Output: +; AX = old clip status +; +mxSetClip PROC FAR + ARG ClipStatus:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [mx_UserClipX1] + mov bx, [mx_UserClipY1] + mov cx, [mx_UserClipX2] + mov dx, [mx_UserClipY2] + cmp [ClipStatus], TRUE + je @@Done + mov ax, [mx_SysClipX1] + mov bx, [mx_SysClipY1] + mov cx, [mx_SysClipX2] + mov dx, [mx_SysClipY2] +@@Done: + mov [mx_ClipX1], ax + mov [mx_ClipY1], bx + mov [mx_ClipX2], cx + mov [mx_ClipY2], dx + + mov al, [ClipStatus] + xchg al, [mx_ClipStatus] + xor ah, ah + + .pop ds + .leave ARG_SIZE +mxSetClip ENDP + +;----------------------------------------------------------- +; +; Returns the current clipping status. +; +; Input: +; none +; Output: +; TRUE (FALSE) if clipping enabled (disabled) +; +mxGetClip PROC FAR + ASSUME ds:NOTHING + mov al, [mx_ClipStatus] + xor ah, ah + ret +mxGetClip ENDP + +;----------------------------------------------------------- +; +; Sets the system clip region and disables user clipping. +; +; Input: +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; old clip status. +; +mxSetSysClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + xor ax, ax ; Sys clip region always starts at (0,0) + mov [mx_SysClipX1], ax + mov [mx_SysClipY1], ax + mov ax, [Width] + dec ax + mov [mx_SysClipX2], ax + mov ax, [Height] + dec ax + mov [mx_SysClipY2], ax + + IF USE286 EQ TRUE + push FALSE + ELSE + mov ax, FALSE + push ax + ENDIF + call mxSetClip + + .pop ds + .leave ARG_SIZE +mxSetSysClipRegion ENDP + +;----------------------------------------------------------- +; +; Sets the clip region. +; +; Input: +; X, Y = coordinates of top left corner of clip region +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; none (no checking on parameters) +; +mxSetClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [X] + mov [mx_UserClipX1], ax + mov ax, [Y] + mov [mx_UserClipY1], ax + mov ax, [Width] + add ax, [X] + dec ax + mov [mx_UserClipX2], ax + mov ax, [Height] + add ax, [Y] + dec ax + mov [mx_UserClipY2], ax + + mov al, [mx_ClipStatus] + cmp al, TRUE + jne @@Exit + push ax + call mxSetClip + +@@Exit: + xor ax, ax + .pop ds + .leave ARG_SIZE +mxSetClipRegion ENDP + +;----------------------------------------------------------- +; +; Returns the current user clip region. +; +; Input: +; X, Y = pointers to integer coordinates of top left corner +; Width = pointer to word width of clip region +; Height = pointer to word height of clip region +; Output: +; AX = current clip status +; +mxGetClipRegion PROC FAR + ARG Height:DWORD, \ + Width:DWORD, \ + Y:DWORD, \ + X:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + mov ax, [mx_UserClipX1] + les di, [X] + mov es:[di], ax + mov ax, [mx_UserClipY1] + les di, [Y] + mov es:[di], ax + + mov ax, [mx_UserClipX2] + sub ax, [mx_UserClipX1] + inc ax + les di, [Width] + mov es:[di], ax + mov ax, [mx_UserClipY2] + sub ax, [mx_UserClipY1] + inc ax + les di, [Height] + mov es:[di], ax + + mov al, [mx_ClipStatus] + xor ah, ah + .pop es, di + .leave ARG_SIZE +mxGetClipRegion ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; This function assumes that a "raw" image has to be clipped, +; so it returns in SI the number of "raw" bytes to skip if +; X, Y were clipped. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; SI = number of bytes to skip before copying a buffer +; DI destroyed +; +subClipImage PROC NEAR + ASSUME ds:NOTHING + xor si, si + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, di + mov di, dx ; Save box height into DI + mul cx ; DX:AX = number of bytes to skip + mov si, ax + mov dx, di ; Restore box height + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax + jge @@DoneHeight ; None, continue + add dx, di ; Clip lines +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + add si, di ; Update skip count + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx + jge @@DoneWidth ; None, exit + add cx, di ; New box width +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipImage ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; DI destroyed +; +subClipBox PROC NEAR + ASSUME ds:NOTHING + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax ; Clipped some point? + jge @@DoneHeight ; No, continue + add dx, di ; Clip lines (DI is negative) +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx ; Clipped some point? + jge @@DoneWidth ; No, exit + add cx, di ; New box width (DI is negative) +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipBox ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxel.asm b/16/x_/mxel.asm new file mode 100755 index 00000000..2c9dda2a --- /dev/null +++ b/16/x_/mxel.asm @@ -0,0 +1,167 @@ +;----------------------------------------------------------- +; +; MXEL.ASM - Mid-point ellipse +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxEllipse + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws an ellipse using the mid-point algorithm. +; +; Input: +; XC, YC = center coordinates +; A = horizontal radius +; B = vertical radius +; Color = ellipse color +; Output: +; none +; Note: +; computes only points in the first quadrant, all other +; points are obtained by symmetry. +; +mxEllipse PROC FAR + ARG Color:BYTE:2, \ + B:WORD, \ + A:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL A2:DWORD, \ + B2:DWORD, \ + CC:DWORD, \ + DD:DWORD, \ + X:DWORD, \ + Y:DWORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + .chk386 mxEllipse, @@Exit + +; Initialize variables + xor eax, eax + mov [X], ax ; X = 0 + mov ax, [A] + mul eax ; EAX = A*A + mov [DD], eax ; DD = A*A + shl eax, 1 + mov [CC], eax ; CC = 2*A*A + shl eax, 1 + mov [A2], eax ; A2 = 4*A*A + movzx edx, [B] + mov [Y], edx + mul edx ; EAX = 4*A*A*B + sub [DD], eax ; DD = A*A - 4*A*A*B + movzx eax, [B] + mul eax ; EAX = B*B + shl eax, 2 ; EAX = 4*B*B + mov [B2], eax ; B2 = 4*B*B + add [CC], eax ; CC = 2*A*A + 4*B*B + add [D1], eax ; DD = A*A - 4*A*A*B + 4*B*B + +; Draw initial points + call subPlot4 + +; First loop +@@Loop1: + mov eax, [X] ; Check slope + mul [B2] + mov ecx, eax + mov eax, [Y] + mul [A2] + sub eax, ecx + sub eax, [CC] ; EAX = Y*A2 - X*B2 - CC + jle @@Done1 ; Crossed critical point, jump to next loop + + mov ecx, [DD] ; Get error + test ecx, ecx ; Positive? + jl @@Draw1 ; No, use default step + + mov eax, 1 + sub eax, [Y] + mul [A2] + shl eax, 1 + add ecx, eax ; Bump error + dec WORD PTR [Y] ; Decrement Y coordinate + +@@Draw1: + mov eax, [X] + shl eax, 1 + add eax, 3 + mul [B2] + add ecx, eax ; Bump error + mov [DD], ecx ; Save error + inc WORD PTR [X] ; Increment X coordinate + + call subPlot4 ; Draw points + jmp @@Loop1 +@@Done1: + +; Initialize variables + shr [B2], 2 + mov eax, [X] + mul eax + add [X] + shl eax, 2 + inc eax + mul [B2] + mov [DD], eax + mov eax, [Y] + mul eax + add [Y] + dec eax + add [Y] + sub eax, [B2] + add [DD], eax + shl [B2], 3 + inc WORD PTR [X] + +; Second loop +@@Loop2: + cmp WORD PTR [Y], 0 + ja @@Done2 + + mov ecx, [DD] + test ecx, ecx + jge @@Draw2 + + mov eax, [X] + inc eax + mul [B2] + add ecx, eax + inc WORD PTR [X] + +@@Draw2: + mov eax, [Y] + shl eax, 1 + sub eax, 3 + neg eax + imul [A2] + add ecx, eax + dec WORD PTR [Y] + + call subPlot4 + jmp @@Loop2 +@@Done2: + +@@Exit: + xor ax, ax + .leave ARG_SIZE +mxEllipse ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxfb.asm b/16/x_/mxfb.asm new file mode 100755 index 00000000..41ea5deb --- /dev/null +++ b/16/x_/mxfb.asm @@ -0,0 +1,194 @@ +;----------------------------------------------------------- +; +; MXFB.ASM - Fill box function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillBox + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN subClipBox : NEAR +EXTRN subHorizontalLineInfo : NEAR + +;----------------------------------------------------------- +; +; Raster op functions. Raster op is limited to OP_MOVE, +; OP_AND, OP_OR and OP_XOR. The VGA hardware is used to +; perform the selected logical functions on up to four +; pixel at a time. +; +subRepFill PROC NEAR + mov ah, al + shr cx, 1 + rep stosw + rcl cx, 1 + rep stosb + ret +subRepFill ENDP +; +subFill PROC NEAR +@@Loop: + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subFill ENDP +; +subRepMove PROC NEAR + mov si, di +@@Loop: + mov ah, ds:[si] ; Dummy read to latch the data + mov ds:[si], al + inc si + loop @@Loop + ret +subRepMove ENDP +; +subMove PROC NEAR +@@Loop: + mov ah, ds:[bx] ; Dummy read to latch the data + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subMove ENDP + +;----------------------------------------------------------- +; +; Fills a rectangle with a specified color. +; +; Input: +; X, Y = X, Y coordinates of rectangle +; Width = width of rectangle +; Height = height of rectangle +; Color = fill color +; Op = raster operator +; Output: +; none +; +; Note: raster op is limited to OP_MOVE, OP_AND, OP_OR and OP_XOR. +; +mxFillBox PROC FAR + ARG Op:WORD, \ + Color:BYTE:2, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL LeftMask:BYTE, \ + RightMask:BYTE, \ + FillFunction:WORD, \ + RepFillFunction:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Clip rectangle + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipBox + jc @@Exit ; Full clipped + + mov [Height], dx ; Save clipped height + call subHorizontalLineInfo ; Get additional info, init DI + mov [Width], cx + mov [LeftMask], al + mov [RightMask], ah + +; Initialize segments + mov ax, [mx_VideoSegment] + mov es, ax ; ES:DI points to pixel + mov ds, ax + cld ; Clear direction flag + +; Select fill functions + mov [FillFunction], OFFSET subFill + mov [RepFillFunction], OFFSET subRepFill + mov ax, [Op] ; Get raster op + cmp al, OP_XOR + ja @@1 ; Assume it's a fill + cmp al, OP_MOVE + je @@1 + .shl al, 3 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set GDC logical function + mov [FillFunction], OFFSET subMove + mov [RepFillFunction], OFFSET subRepMove +@@1: + +; Fill left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 ; Nothing to do, go to center block + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + inc di ; Update starting video offset + +; Fill center block +@@C0: + mov cx, [Width] + jcxz @@R0 ; Nothing to do, go to right block + mov dx, TS + mov ax, 0F02h + out dx, ax ; Write to all planes + mov al, [Color] + mov bx, di + mov dx, [Height] + push di ; Save pixel address +@@C1: + mov di, bx ; Update video offset + call [RepFillFunction] ; Fill current scan line + mov cx, [Width] ; Restore byte count + add bx, [mx_BytesPerLine] ; Bump to next scan line + dec dx ; Done all lines? + jnz @@C1 ; No, continue + pop di ; Restore pixel address + add di, [Width] ; Go to right block + +; Fill right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done ; Nothing to do, exit + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + +; Restore VGA registers +@@Done: + mov dx, GDC + mov ax, 0003h + out dx, ax ; Set logical function to "move" + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillBox ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxfp.asm b/16/x_/mxfp.asm new file mode 100755 index 00000000..8eea25be --- /dev/null +++ b/16/x_/mxfp.asm @@ -0,0 +1,326 @@ +;----------------------------------------------------------- +; +; MXFP.ASM - Fade palette function +; Copyright (c) 1992-1994 ARTIS s.r.l. +; Author: Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxFadePalette + +MAXCOLOR EQU 256 +FADE_IN EQU 0 +FADE_OUT EQU 1 + +; The actual speed of fading depends on the number of passes (FADE_SPEED) and +; the delay between two consecutive passes (FADE_DELAY). Below are the +; default values, used when no parameters are specified. +; +FADE_DELAY EQU 1 ; Vert. retraces between video updates +FADE_SPEED EQU 48 ; Speed of effect (max 127) + +; Bit field record for fade commands +; +FADE_COMMAND RECORD fpDELAY:8,fpSPEED:7,fpDIRECTION:1 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'Copyright (c) 1992-1994 ARTIS s.r.l. All rights reserved.' + +;----------------------------------------------------------- +; +; Fades a VGA palette. +; +; Input: +; Buffer = pointer to source/destination palette +; Command = fading direction and optional parameters +; Start = index of first color to fade +; Count = number of color to fade +; Red = destination red +; Green = destination green +; Blue = destination blue +; Output: +; none +; Notes: +; - about 1.5 Kbytes of stack space are needed for internal buffers; +; - the Command argument usually is 0 to fade in and 1 to fade out, +; however additional parameters may be specified. To set the effect +; speed, i.e. the number of iterations needed to completely fade a +; palette, shift the value one bit left and "or" it with the +; direction bit (range is 0..127). To set the delay between two +; consecutive passes, shift it eight bits left (range is 0..255). +; +mxFadePalette PROC FAR + ARG bBlue:WORD, \ + bGreen:WORD, \ + bRed:WORD, \ + wCount:WORD, \ + wStartIdx:WORD, \ + wCommand:WORD, \ + vfpPalette:DWORD = ARG_SIZE + LOCAL bSPalette:BYTE:MAXCOLOR*3, \ + bDPalette:BYTE:MAXCOLOR*3, \ + bLoopIndex:BYTE, \ + bLoopStep:BYTE, \ + bLoopCount:BYTE, \ + wDelay:WORD, \ + wSpeed:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push si, di, ds, es ; Save registers +; +; Check parameters and setup variables +; +@@GetDelay: + mov [wDelay], FADE_DELAY ; Set default delay + mov ax, [wCommand] ; Get command word + and ax, MASK fpDELAY ; Mask delay command + jz @@GetSpeed ; No command, get speed + IF USE286 EQ TRUE + shr ax, fpDELAY + ELSE + mov cl, fpDELAY ; Get size of delay field + shr ax, cl ; Right justify the field + ENDIF + mov [wDelay], ax ; Set new delay + +@@GetSpeed: + mov ax, [wCommand] ; Get command + and ax, MASK fpSPEED ; Mask speed + IF USE286 EQ TRUE + shr ax, fpSPEED + ELSE + mov cl, fpSPEED ; Get size of speed field + shr ax, cl ; Right justify the field + ENDIF + or ax, ax ; Any speed specified? + jnz @@SetVariables ; Yes, set variables + mov ax, FADE_SPEED ; Set default speed + +@@SetVariables: + mov [wSpeed], ax ; Set speed + inc ax ; Number of iterations + mov [bLoopCount], al ; Set loop count + mov [bLoopStep], 1 ; Assume we're fading in + mov [bLoopIndex], 0 +; +; Check bounds for bad values +; + mov ax, [wStartIdx] ; Get first index + cmp ax, MAXCOLOR ; Is in the valid range? + jae @@Exit ; No, exit + add ax, [wCount] ; Get last index + cmp ax, MAXCOLOR ; Is in the valid range? + jbe @@BoundsOk ; Yes, continue + mov ax, MAXCOLOR + sub ax, [wStartIdx] + mov [wCount], ax ; Set count to maximum value + or ax, ax + jz @@Exit ; Nothing to do, exit +@@BoundsOk: +; +; Copy the source palette in a local array: if we fade in it's ready to +; use, otherwise we'll overwrite it later +; + mov cx, [wCount] + mov ax, cx + shl ax, 1 + add cx, ax ; CX = wCount * 3 + mov ax, ss + mov es, ax + lea di, [bSPalette] ; ES:DI points to local palette + mov ax, [wStartIdx] + mov si, ax + shl ax, 1 + add ax, si + lds si, [vfpPalette] ; DS:SI points to user palette + add si, ax ; Skip unused entries + cld + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb +; +; Check direction +; + test [wCommand], MASK fpDIRECTION ; Are we fading in? + jz @@Main ; Yes, ok to continue + mov ax, [wSpeed] ; Get speed + mov [bLoopIndex], al ; Exchange first and last index + mov [bLoopStep], -1 ; Move backward + mov ax, ss ; Overwrite our copy of + mov ds, ax ; user palette with the + mov es, ax ; current active palette + lea di, [bSPalette] + mov ax, [wStartIdx] + mov cx, [wCount] + call ReadPalette ; Read current palette +; +; Prepare variables and registers for fading +; +@@Main: + mov bh, BYTE PTR [bRed] ; Destination red + and bh, 00111111b ; Be sure it's a valid VGA value + mov bl, BYTE PTR [bGreen] ; Destination green + and bl, 00111111b ; Be sure it's a valid VGA value + mov dh, BYTE PTR [bBlue] ; Destination blue + and dh, 00111111b ; Be sure it's a valid VGA value + mov dl, [bLoopIndex] ; Loop index + mov ax, ss ; All tables are stored + mov ds, ax ; in the stack segment, + mov es, ax ; set DS and ES +; +; Main loop +; +@@Loop: + mov ax, [wCount] ; Store count in AX + mov cx, [wSpeed] ; Set maximum speed in CX + lea si, [bSPalette] ; DS:SI points to source palette + lea di, [bDPalette] ; ES:DI points to dest. palette + call RecalcPalette ; Build a faded palette + + .push bx, dx ; Save registers we need + lea si, [bDPalette] ; DS:SI points to palette + mov ax, [wStartIdx] ; First index to write + mov bx, [wCount] ; Total entries to write + mov cx, [wDelay] ; Fade delay between updates + call WritePalette ; Write palette + .pop bx, dx ; Restore BX and DX + + add dl, [bLoopStep] ; Change fade intensity + dec [bLoopCount] ; Done? + jnz @@Loop ; No, loop again + +@@Exit: + .pop si, di, ds, es ; Restore registers + .leave ARG_SIZE +mxFadePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Calculates a partially faded palette. +; +; Input: +; AX = number of entries in palette +; CX = maximum fade intensity (same as fade speed) +; DS:SI = pointer to source palette +; ES:DI = pointer to destination palette +; BH = destination red +; BL = destination green +; DH = destination blue +; DL = relative intensity of destination palette +; Note: +; it's important that a new palette can be calculated in less +; than 1/70th of second. Fading to any RGB value requires use +; of "imul" instructions: "idiv" may be replaced with faster +; "sar", but only when the number of passes is a power of two, +; thus reducing the range of selectable speeds. +; In both cases an extimate of CPU cycles required by this +; procedure shows that it's too slow to run on a 4.77 Mhz 8086 +; CPU and a 256 color palette, so we keep "idiv" and hope +; the target machine to be at least a 6 Mhz 80286 (that's not +; asking too much...). +; +RecalcPalette PROC NEAR + cld + push bp ; Save BP + mov bp, ax ; Copy counter in BP +@@Loop: + lodsb ; Red: read value + sub al, bh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bh ; Add destination value... + stosb ; ...and store it + lodsb ; Green: read value + sub al, bl ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bl ; Add destination value... + stosb ; ...and store it + lodsb ; Blue: read value + sub al, dh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, dh ; Add destination value... + stosb ; ...and store it + dec bp + jnz @@Loop + pop bp ; Restore BP + ret +RecalcPalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Writes a 256 color palette. +; +; Input: +; AX = index of first color to write +; BX = number of colors to write (each color is an RGB triplet) +; CX = number of vertical retraces to wait before writing to DACs +; DS:SI = pointer to first entry of palette +; +WritePalette PROC NEAR + ASSUME ds:NOTHING + mov ah, al ; Save index + mov dx, 03DAh ; Input status register +@@Delay1: + in al, dx + test al, 08h + jnz @@Delay1 ; Wait for display mode +@@Delay2: + in al, dx + test al, 08h + jz @@Delay2 ; Wait for vertical retrace mode + loop @@Delay1 ; Repeat CX times +@@Write: + mov cx, bx ; Get number of colors + mov dx, 03C8h ; PEL write address register + mov al, ah ; Restore index + out dx, al ; Select index of first color + inc dx ; PEL data register + cld ; Move forward + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + ret +WritePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Reads the current palette. +; +; Input: +; AX = index of first color to read +; CX = number of colors +; ES:DI = pointer to destination buffer +; +ReadPalette PROC NEAR + mov dx, 03C7h + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop + ret +ReadPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxgc.asm b/16/x_/mxgc.asm new file mode 100755 index 00000000..85edf7a6 --- /dev/null +++ b/16/x_/mxgc.asm @@ -0,0 +1,54 @@ +;----------------------------------------------------------- +; +; MXGC.ASM - Get color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the selected DAC register. +; +; Input: +; Index = color index (0-255) +; R, G, B = byte pointers to red, green and blue +; Output: +; none +; +mxGetColor PROC FAR + ARG B:DWORD, \ + G:DWORD, \ + R:DWORD, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + + lds si, [R] + in al, dx + mov ds:[si], al + lds si, [G] + in al, dx + mov ds:[si], al + lds si, [B] + in al, dx + mov ds:[si], al + + .pop ds, si + .leave ARG_SIZE +mxGetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxgi.asm b/16/x_/mxgi.asm new file mode 100755 index 00000000..7037d411 --- /dev/null +++ b/16/x_/mxgi.asm @@ -0,0 +1,132 @@ +;----------------------------------------------------------- +; +; MXGI.ASM - Get image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGetImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies an image from screen to memory. +; +; Input: +; Image = pointer to buffer for image +; X, Y = coordinates of image on screen +; Width = width of image in pixels +; Height = height of image in pixels +; Output: +; none +; +mxGetImage PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + Count:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov si, bx + shr si, 1 + shr si, 1 + add si, ax + mov [PixelOffset], si + mov ds, [mx_VideoSegment] ; DS:SI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov di, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[di], bx + shr al, 1 + adc bx, 0 + dec di + dec di + jge @@PatchLoop + +; Get image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov es, WORD PTR Image[2] ; ES:DI will point to image + mov ah, [ReadPlane] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov di, WORD PTR Image[0] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov si, [PixelOffset] ; DS:SI points to video memory +@@Loop: + .push si, di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move +@@MoveLoop: + movsb + add di, 3 + dec cx + jnz @@MoveLoop + .pop si, di + add di, [Width] ; Go to next image line + add si, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc ah + test ah, 04h ; Plane wraparound? + jz @@PlaneOk ; No + inc [PixelOffset] ; Yes, bump video pointer + and ah, 03h +@@PlaneOk: + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGetImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxgm.asm b/16/x_/mxgm.asm new file mode 100755 index 00000000..a67476a0 --- /dev/null +++ b/16/x_/mxgm.asm @@ -0,0 +1,63 @@ +;----------------------------------------------------------- +; +; MXGM.ASM - Gamma correction +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGammaCorrect + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +mx_tblGamma LABEL BYTE + DB 00, 10, 14, 17, 19, 21, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34 + DB 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46 + DB 47, 48, 48, 49, 49, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55 + DB 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63 + +;----------------------------------------------------------- +; +; Correct palette colors (gamma is 2.3). +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gamma corrected) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxGammaCorrect PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit ; Exit now if nothing to do + lds si, [SPal] + les di, [DPal] + mov bx, OFFSET mx_tblGamma ; Setup BX for XLAT instruction + cld + mov ax, cx ; AX = Count + add cx, cx ; CX = Count*2 + add cx, ax ; CX = Count*3 +@@Loop: + lodsb + xlat mx_tblGamma + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxGammaCorrect ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxgp.asm b/16/x_/mxgp.asm new file mode 100755 index 00000000..6c143173 --- /dev/null +++ b/16/x_/mxgp.asm @@ -0,0 +1,56 @@ +;----------------------------------------------------------- +; +; MXGP.ASM - Get palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to get +; Count = number of color to get +; Output: +; none +; +mxGetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + les di, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop ; Loop until done + + .pop es, di + .leave ARG_SIZE +mxGetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxgv.asm b/16/x_/mxgv.asm new file mode 100755 index 00000000..2a54b1d0 --- /dev/null +++ b/16/x_/mxgv.asm @@ -0,0 +1,25 @@ +;----------------------------------------------------------- +; +; MXGV.ASM - Get version function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetVersion + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the library version. +; +mxGetVersion PROC FAR + mov ax, MXVERSION + ret +mxGetVersion ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxhl.asm b/16/x_/mxhl.asm new file mode 100755 index 00000000..049a0566 --- /dev/null +++ b/16/x_/mxhl.asm @@ -0,0 +1,76 @@ +;----------------------------------------------------------- +; +; MXHL.ASM - Horizontal line mask utility +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC subHorizontalLineInfo + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +tblLeftSize DW 00h, 03h, 02h, 01h +tblLeftMask DB 00h, 0Eh, 0Ch, 08h +tblRightMask DB 00h, 01h, 03h, 07h +tblPatchMask DB 02h, 06h + +;----------------------------------------------------------- +; +; Prepares register for fast horizontal line drawing. +; +; Input: +; BX, AX = X, Y address of left pixel +; CX = line width +; Output: +; DI = left pixel offset in video memory +; AL = left block write plane mask (0 = none) +; AH = right block write plane mask (0 = none) +; CX = center block width in 4-pixel blocks +; +subHorizontalLineInfo PROC NEAR + ASSUME ds:NOTHING + + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax ; Offset of left pixel + + and bx, 03h + mov al, tblLeftMask[bx] + shl bx, 1 + sub cx, tblLeftSize[bx] + jge @@1 ; Ok to continue + +; Special case: start and end in the middle of a 4-pixel block. +; There are only three cases: +; Pixels Left mask CX CX+2 Patch mask Result +; 1) ..o. ..xx -1 1 .xx. ..x. +; 2) .oo. .xxx -1 1 .xx. .xx. +; 3) .o.. .xxx -2 0 .x.. .x.. +; All other cases are automatically handled with the standard masks. + mov bx, cx + inc bx + inc bx + and al, tblPatchMask[bx] ; Combine masks + xor ah, ah ; No right block + xor cx, cx ; No center block + jmp @@Exit + +@@1: + mov bx, cx + and bx, 03h + mov ah, tblRightMask[bx] + shr cx, 2 + +@@Exit: + ret +subHorizontalLineInfo ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxit.asm b/16/x_/mxit.asm new file mode 100755 index 00000000..c0d9cedd --- /dev/null +++ b/16/x_/mxit.asm @@ -0,0 +1,98 @@ +;----------------------------------------------------------- +; +; MXIT.ASM - Initialization/termination functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxInit +PUBLIC mxTerm + +PUBLIC mx_VideoSegment +PUBLIC mx_CodeSegment + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'MODEX library - Copyright (c) 1992-1994 Alessandro Scotti' + +mx_VideoSegment DW 0A000h +mx_CodeSegment DW SEG MX_TEXT + +;----------------------------------------------------------- +; +; Initialization. +; +; Input: +; none +; Output: +; AX = 0 on success +; +mxInit PROC FAR + LOCAL Result:WORD, \ + VideoSeg:WORD, \ + CStoDSalias:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov [Result], -1 ; Assume an error + mov [VideoSeg], 0A000h ; Real mode video segment + mov [CStoDSalias], cs ; Real mode data alias for CS + +; Check if running in protected mode under DPMI + mov ax, 1686h + int 2Fh + or ax, ax + jnz @@1 ; DPMI not found, continue in real mode + +; Get a data alias for CS + mov ax, 000Ah ; DMPI: create data alias + mov bx, cs + int 31h + jc @@Exit ; Exit if service failed + mov [CStoDSalias], ax ; Save data alias for CS +; Get a protected-mode selector for the video segment + mov ax, 0002h + mov bx, 0A000h ; Real mode segment of video + int 31h ; DPMI: get segment selector + jc @@Exit ; Exit if service failed + mov [VideoSeg], ax ; Save protected mode video selector + +; Initialize variables +@@1: + mov ds, [CStoDSalias] + ASSUME ds:MX_TEXT + mov [mx_CodeSegment], ds + mov ax, [VideoSeg] + mov [mx_VideoSegment], ax + +; Don't bother with VGA check for now... + + mov [Result], 0 + +@@Exit: + mov ax, [Result] + .pop ds, si, es, di + .leave +mxInit ENDP + +;----------------------------------------------------------- +; +; Termination. +; +; Input: +; none +; Output: +; always 0. +; +mxTerm PROC FAR + ASSUME ds:NOTHING + xor ax, ax + ret +mxTerm ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxll.asm b/16/x_/mxll.asm new file mode 100755 index 00000000..34fec043 --- /dev/null +++ b/16/x_/mxll.asm @@ -0,0 +1,82 @@ +;----------------------------------------------------------- +; +; MXLL.ASM - Load latches +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxLoadLatches + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD + +;----------------------------------------------------------- +; +; Loads the specified value into the VGA latches. +; +; Input: +; BL = value to load into latches +; Output: +; none +; Changes: +; bit mask register to FFh; +; function select register to "move"; +; write mode to 00h. +; Note: +; this is for internal use only. +; +mxLoadLatches PROC NEAR + ASSUME ds:NOTHING + + .push ds, si + mov dx, GDC + mov ax, 0FF08h + out dx, ax ; Set bit mask to FFh + mov ax, 0003h + out dx, ax ; Set function to "move" + mov ax, 0005h + out dx, ax ; Set write mode + mov ax, [mx_VideoSegment] + mov ds, ax + mov si, 0FFFFh + mov bh, 8 ; BH = write plane mask + mov cx, 3 ; CX = count = read plane +; Saves old values and force BL into latches +@@SetLoop: + mov dx, GDC + mov al, 04h + mov ah, cl + out dx, ax ; Select read plane + mov dx, TS + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + mov al, ds:[si] + push ax + mov ds:[si], bl + mov al, ds:[di] ; Force value into latch + shr bh, 1 ; Next write plane + loop @@SetLoop +; Restore previous values + mov cx, 3 + mov bh, 8 + mov dx, TS +@@ResetLoop: + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + pop ax + mov ds:[si], al + shr bh, 1 ; Next write plane + loop @@ResetLoop +; Exit + .pop ds, si + ret +mxLoadLatches ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxln.asm b/16/x_/mxln.asm new file mode 100755 index 00000000..fbc4ab94 --- /dev/null +++ b/16/x_/mxln.asm @@ -0,0 +1,414 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Line function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblDrawFunc LABEL WORD + DW subWidthMove + DW subHeightMove + DW subWidthOp + DW subHeightOp + +;----------------------------------------------------------- +; +; Draws a line from (X1,Y1) to (X2,Y2) using the Bresenham +; algorithm. +; +; Input: +; X1, Y1 = start point +; X2, Y2 = end point +; Color = line color +; Op = raster operator +; Output: +; none +; +; Note: the end point (X2,Y2) *IS* drawed. I don't like this very much +; but clipping is much simpler. +; +mxLine PROC FAR + ARG Op:WORD, \ + Color:WORD, \ + Y2:WORD, \ + X2:WORD, \ + Y1:WORD, \ + X1:WORD = ARG_SIZE + LOCAL Width:WORD, \ + Height:WORD, \ + ErrorAdd:WORD, \ + ErrorSub:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD, \ + P1:BYTE, \ + P2:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + ASSUME ds:NOTHING + + mov ax, [X1] + mov bx, [Y1] + mov cx, [X2] + mov dx, [Y2] + call subClipLine + jc @@Exit ; Line is full clipped + +; Get width + mov si, cx + xchg ax, si ; SI = X1, AX = X2 + sub ax, si + jge @@1 +; Swap points, we want X1 < X2 + xchg si, cx ; Swap X1 and X2 + xchg bx, dx ; Swap Y1 and Y2 + neg ax +@@1: + mov [Width], ax + +; Get height + mov cx, [mx_BytesPerLine] ; We don't need X2 anymore + mov ax, dx + sub ax, bx + jge @@2 + neg cx ; Move from bottom to top + neg ax ; Get absolute value of AX +@@2: + mov [Height], ax + mov [DeltaY], cx + +; Get pixel address and write plane + mov ax, bx + mul [mx_BytesPerLine] + mov cx, si ; CX = X1 + shr si, 1 + shr si, 1 + add si, ax ; SI = pixel offset + and cl, 03h + mov ax, 1102h + shl ah, cl + mov [WritePlane], ah + mov dx, TS + out dx, ax ; Set write plane + mov ax, [mx_VideoSegment] + mov ds, ax ; DS:SI points to (X1,Y1) + +; Select the function to handle the drawing loop + xor bx, bx + mov al, BYTE PTR [Op] + cmp al, OP_MOVE + je @@3 + and al, 03h + shl al, 1 + shl al, 1 + shl al, 1 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set logical function + inc bx + inc bx +@@3: + mov ax, [Width] + mov cx, [Height] +; Horizontal, vertical and diagonal lines are not optimized yet + cmp ax, cx + jae @@4 + inc bx +@@4: + shl bx, 1 + call tblDrawFunc[bx] + +; Reset logical function if needed + cmp BYTE PTR [Op], OP_MOVE + je @@Exit + mov ax, 0003h + mov dx, GDC + out dx, ax + +@@Exit: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses a variation of the Cohen-Sutherland algorithm developed +; by Victor Duvanenko. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +subClipLine PROC NEAR + mov di, ax ; Copy X1 to DI and free AX + mov si, dx ; Copy Y2 to SI and free DX +; Compute clip codes for point (X2,Y2)=(CX,SI) + xor al, al +@@P2X1: cmp cx, [mx_ClipX1] + jge @@P2X2 + or al, 1 +@@P2X2: cmp cx, [mx_ClipX2] + jle @@P2Y1 + or al, 2 +@@P2Y1: cmp si, [mx_ClipY1] + jge @@P2Y2 + or al, 4 +@@P2Y2: cmp si, [mx_ClipY2] + jle @@P2XY + or al, 8 +@@P2XY: mov [P2], al +; Compute clip codes for point (X1,Y1)=(DI,BX) + xor al, al +@@P1X1: cmp di, [mx_ClipX1] + jge @@P1X2 + or al, 1 +@@P1X2: cmp di, [mx_ClipX2] + jle @@P1Y1 + or al, 2 +@@P1Y1: cmp bx, [mx_ClipY1] + jge @@P1Y2 + or al, 4 +@@P1Y2: cmp bx, [mx_ClipY2] + jle @@P1XY + or al, 8 +@@P1XY: mov [P1], al +; Check codes for trivial cases + mov ah, [P2] + test al, ah ; Is line invisible? + jnz @@FullClip ; Yes, exit + or ah, al ; Both points clipped? + jz @@Done ; Yes, exit +; Calculate deltas + mov ax, cx + sub ax, di + mov [DeltaX], ax + mov ax, si + sub ax, bx + mov [DeltaY], ax + mov al, [P1] ; Init clipping code +; Clipping loop +@@ClipLoop: + test al, al ; Is first point clipped? + jnz @@ClipX1 ; No, continue + xchg cx, di ; Swap points... + xchg bx, si + xchg al, [P2] ; ...and codes +; Clip left: Y1 = Y1 + DeltaY*(mx_ClipX1-X1)/DeltaX +@@ClipX1: + test al, 1 + jz @@ClipX2 + mov ax, [mx_ClipX1] + sub ax, di + mov di, [mx_ClipX1] + jmp @@ClipX1X2 +; Clip right: Y1 = Y1 + DeltaY*(mx_ClipX2-X1)/DeltaX +@@ClipX2: + test al, 2 + jz @@ClipY1 + mov ax, [mx_ClipX2] + sub ax, di + mov di, [mx_ClipX2] +@@ClipX1X2: + imul [DeltaY] + idiv [DeltaX] + add bx, ax + mov al, 8 + cmp bx, [mx_ClipY2] + jg @@CheckLoop + mov al, 4 + cmp bx, [mx_ClipY1] + jl @@CheckLoop + xor al, al + jmp @@CheckLoop +; Clip top: X1 = X1 + DeltaX*(mx_ClipY1-Y1)/DeltaY +@@ClipY1: + test al, 4 + jz @@ClipY2 + mov ax, [mx_ClipY1] + sub ax, bx + mov bx, [mx_ClipY1] + jmp @@ClipY1Y2 +; Clip bottom: X1 = X1 + DeltaX*(mx_ClipY2-Y1)/DeltaY +@@ClipY2: + mov ax, [mx_ClipY2] + sub ax, bx + mov bx, [mx_ClipY2] +@@ClipY1Y2: + imul [DeltaX] + idiv [DeltaY] + add di, ax + mov al, 1 + cmp di, [mx_ClipX1] + jl @@CheckLoop + mov al, 2 + cmp di, [mx_ClipX2] + jg @@CheckLoop + xor al, al +@@CheckLoop: + mov ah, [P2] + test al, ah + jnz @@FullClip + or ah, al + jnz @@ClipLoop + +@@Done: + mov ax, di + mov dx, si + clc + ret +@@FullClip: + stc + ret +subClipLine ENDP + +; Called when Width >= Height and Op = OP_MOVE +subWidthMove PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthMove ENDP + +; Called when Width < Height and Op = OP_MOVE +subHeightMove PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightMove ENDP + +; Called when Width >= Height and Op <> OP_MOVE +subWidthOp PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] ; Latch data + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthOp ENDP + +; Called when Width < Height and Op <> OP_MOVE +subHeightOp PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightOp ENDP + +mxLine ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxot.asm b/16/x_/mxot.asm new file mode 100755 index 00000000..62547665 --- /dev/null +++ b/16/x_/mxot.asm @@ -0,0 +1,330 @@ +;----------------------------------------------------------- +; +; MXOT.ASM - Text functions +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES ; We use the reserved name 'WIDTH' +INCLUDE MODEX.DEF + +PUBLIC mxOutChar +PUBLIC mxOutText +PUBLIC mxSetFont +PUBLIC mxSetTextColor +PUBLIC mxGetTextStep +PUBLIC mxSetTextStep + +MAX_WIDTH EQU 16 ; Must be <= 16 +MAX_HEIGHT EQU 32 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD +EXTRN mxPutImage : FAR + +; Default 8x8 font +fnt_Default LABEL + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW OP_MOVE ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +;----------------------------------------------------------- +; +; Sets the current font. +; +; Input: +; Font = pointer to font data +; Width = width of font character in pixels +; Height = height of font character in pixels +; Output: +; AX = 0 on success, else invalid parameters +; +; Note: when the high word of Font (i.e. the segment) is zero, the low +; word is used to select one of the system fonts. +; +mxSetFont PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Font:DWORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, WORD PTR Font[2] ; Get font segment + test ax, ax ; Null segment? + jnz @@UserFont ; No, install user font + +; Install system font + mov ax, WORD PTR Font[0] ; Get font number + cmp ax, MX_MAXSYSFONT ; Check range + jb @@SystemFont + xor ax, ax ; Out of range, use default font +@@SystemFont: + shl ax, 1 + shl ax, 1 + mov bx, ax + mov ax, tbl_SystemFont[bx] ; Get font offset + mov WORD PTR mx_FontPtr[0], ax + mov WORD PTR mx_FontPtr[2], cs + mov al, BYTE PTR tbl_SystemFont[bx+2] + xor ah, ah + mov [mx_FontWidth], ax + mov [mx_DeltaX], ax + mov dl, BYTE PTR tbl_SystemFont[bx+3] + xor dh, dh + mov [mx_FontHeight], dx + mul dx + mov [mx_FontCharSize], ax + mov [mx_DeltaX], ax + xor ax, ax + mov [mx_DeltaY], ax + jmp @@Exit + +; Install user font +@@UserFont: + mov ax, -1 ; Assume an error + mov bx, [Width] + cmp bx, MAX_WIDTH + ja @@Exit ; Invalid character width + mov dx, [Height] + cmp dx, MAX_HEIGHT + ja @@Exit ; Invalid character height + mov [mx_FontWidth], bx + mov [mx_FontHeight], dx + mov ax, bx + add ax, 7 + .shr ax, 3 + mul dx + mov [mx_FontCharSize], ax + mov ax, WORD PTR Font[0] + mov WORD PTR mx_FontPtr[0], ax + mov ax, WORD PTR Font[2] + mov WORD PTR mx_FontPtr[2], ax + xor ax, ax + +@@Exit: + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetFont ENDP + +;----------------------------------------------------------- +; +; Sets the text color and raster op. +; +; Input: +; Color = text color (foreground + background*256) +; Op = raster op +; Output: +; none +; +mxSetTextColor PROC FAR + ARG Op:WORD, \ + Color:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [Color] + mov [mx_FontColor], ax + mov ax, [Op] + mov [mx_FontOp], ax + + xor ax, ax + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetTextColor ENDP + +;----------------------------------------------------------- +; +; Writes a character using the current font and attributes. +; +; Input: +; X, Y = video coordinates +; C = character to print +; Output: +; none +; +mxOutChar PROC FAR + ARG C:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \ + Count:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Gets the pointer to font data for the selected character + lds si, DWORD PTR [mx_FontPtr] + mov al, [C] + xor ah, ah + mul [mx_FontCharSize] ; Offset into font + add si, ax ; DS:SI -> font data for character + +; Converts font data into a 256-color linear image + mov ax, ss + mov es, ax + lea di, [Image] + mov dx, [mx_FontColor] + mov ax, [mx_FontHeight] + mov [Count], ax +@@HeightLoop: + mov cx, [mx_FontWidth] + mov bh, ds:[si] + inc si ; Get a byte from font data + cmp cx, 8 + jbe @@WidthLoop ; Ok for width <= 8 + mov bl, ds:[si] ; Get another byte + inc si +@@WidthLoop: + mov al, dl ; Assume foreground color + shl bx, 1 ; Is font bit set? + jc @@1 ; Yes, foreground is just great + mov al, dh ; Get background color +@@1: + mov es:[di], al ; Put pixel into image + inc di + dec cx + jnz @@WidthLoop + dec [Count] + jnz @@HeightLoop + +; Now pass image to mx_PutImage + lea ax, [Image] + push es + push ax ; Pointer to image + push [X] + push [Y] ; Image coordinates + push [mx_FontWidth] + push [mx_FontHeight] ; Image size + push [mx_FontOp] ; Raster op + call mxPutImage ; Write character + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxOutChar ENDP + +;----------------------------------------------------------- +; +; Writes a string at the coordinates specified. +; +; Input: +; X, Y = text coordinates +; S = pointer to ASCIIZ string +; Output: +; none +; +mxOutText PROC FAR + ARG S:DWORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [S] +@@Loop: + mov al, ds:[si] + test al, al ; End of string? + jz @@Exit ; Yes, exit + inc si + push [X] ; Display character + push [Y] + push ax + call mxOutChar + mov ax, [mx_DeltaX] + add [X], ax ; Bump X coordinate + mov ax, [mx_DeltaY] + add [Y], ax ; Bump Y coordinate + dec [Count] + jnz @@Loop + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE + ret +mxOutText ENDP + +;----------------------------------------------------------- +; +; Sets the distance between characters. +; +; Input: +; DeltaX = horizontal distance in pixels +; DeltaY = vertical distance in pixels +; Output: +; none +; +; Note: this function may be used to set the text direction. +; +mxSetTextStep PROC FAR + ARG DeltaY:WORD, \ + DeltaX:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [DeltaX] + mov [mx_DeltaX], ax + mov ax, [DeltaY] + mov [mx_DeltaY], ax + + .pop ds + .leave ARG_SIZE +mxSetTextStep ENDP + +;----------------------------------------------------------- +; +; Gets the current distance between characters. +; +; Input: +; DeltaX = pointer to horizontal distance in pixels (integer) +; DeltaY = pointer to vertical distance in pixels (integer) +; Output: +; none +; +mxGetTextStep PROC FAR + ARG DeltaY:DWORD, \ + DeltaX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + mov ax, [mx_DeltaX] + lds si, [DeltaX] + mov ds:[si], ax + mov ax, [mx_DeltaY] + lds si, [DeltaY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetTextStep ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxpb.asm b/16/x_/mxpb.asm new file mode 100755 index 00000000..8c6aa449 --- /dev/null +++ b/16/x_/mxpb.asm @@ -0,0 +1,22 @@ +;----------------------------------------------------------- +; +; MXPB.ASM - Scan buffer for convex polygon fills +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mx_ScanBuffer + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +ALIGN 4 + +mx_ScanBuffer LABEL + DW POLYSCANBUFSIZE DUP(?) + +MX_TEXT ENDS +END diff --git a/16/x_/mxpf.asm b/16/x_/mxpf.asm new file mode 100755 index 00000000..db0da898 --- /dev/null +++ b/16/x_/mxpf.asm @@ -0,0 +1,420 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + Y2 DW ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@Exit + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@Exit + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +@@Exit: + pop bp ; Restore BP + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxFillPoly PROC FAR + ARG Color:WORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc dx + inc di + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 2 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + ja @@ClipYLoop ; Not clipped, continue +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov dx, TS + mov al, 02h + out dx, ax + mov ax, [Color] + mov dx, [mx_BytesPerLine] + shr cx, 1 + jnc @@FillScan + mov es:[di], al + add di, dx + jcxz @@DrawNext +@@FillScan: + mov es:[di], al + add di, dx + mov es:[di], al + add di, dx + dec cx + jnz @@FillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxpg.asm b/16/x_/mxpg.asm new file mode 100755 index 00000000..caa7cf1b --- /dev/null +++ b/16/x_/mxpg.asm @@ -0,0 +1,589 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill with Gouraud shading +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGouraudPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + E1 DB ? + C1 DB ? + Y2 DW ? + E2 DB ? + C2 DB ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; Also interpolates color for shading. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; DX = start color +; AX = end color +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + push di ; Save scan info offset + push cx ; Save height + push ax ; Save colors + push dx + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@GetColorInfo + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@GetColorInfo + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +; Now get the color info +@@GetColorInfo: + pop bx ; Restore colors + pop ax + pop cx ; Height + pop di ; ES:DI -> scan info + + sub ax, bx ; Get color range + jg @@CL2R + jl @@CR2L + +; Special case: same color + mov ah, bl + mov al, 80h +@@CV: + mov WORD PTR es:[di].E1, ax + add di, SIZE TSCAN + dec cx + jnz @@CV + jmp @@Exit + +; Scan left to right +@@CL2R: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@CL2RLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@CL2RLoop + jmp @@Exit + +; Scan right to left +@@CR2L: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h + +@@CR2LLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@CR2LLoop + +@@Exit: + pop bp + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a scan column. +; +; Input: +; DS:SI = current TSCAN +; ES:DI = address of top pixel +; CX = number of pixels to write +; DX = base color +; Output: +; none +; +subFillScan PROC NEAR + mov ax, WORD PTR ds:[si].E2 + mov bx, WORD PTR ds:[si].E1 + cmp ah, bh + jg @@L2R ; Color increases + jl @@R2L ; Color decreases + +; Special case: color doesn't change + add ax, dx + mov dx, [mx_BytesPerLine] +@@V: + mov es:[di], ah + add di, dx + dec cx + jnz @@V + ret + +; Color increases +@@L2R: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@L2RLoop: + mov es:[di], ah + add dx, bx + adc ax, bp + add di, si + dec cx + jnz @@L2RLoop + .pop bp, si + ret + +; Color decreases +@@R2L: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + neg ax + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@R2LLoop: + mov es:[di], ah + sub dx, bx + sbb ax, bp + add di, si + dec cx + jnz @@R2LLoop + .pop bp, si + ret +subFillScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; Interpolates pixel colors using the Gouraud algorithm. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Colors = array of colors (integer) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxGouraudPoly PROC FAR + ARG Color:WORD, \ + Colors:DWORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc di + inc dx + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 3 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom, need to scale colors too + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov ax, WORD PTR ds:[si].E1 + sub ax, WORD PTR ds:[si].E2 + imul bx + idiv cx + add WORD PTR ds:[si].E2, ax + mov ax, ds:[si].Y1 ; Restore AX and CX + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top, need to scale colors too + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + jbe @@ClipYClip ; Full clipped, skip + mov ax, WORD PTR ds:[si].E2 + sub ax, WORD PTR ds:[si].E1 ; AX = color distance + imul dx + idiv cx + add WORD PTR ds:[si].E1, ax ; Update starting color + jmp @@ClipYLoop +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 + mov ax, [Color] ; Make 8:8 fixed color + mov ah, al + xor al, al + mov [Color], ax +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + out dx, ax + mov dx, [Color] + call subFillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGouraudPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxpi.asm b/16/x_/mxpi.asm new file mode 100755 index 00000000..9e8525f5 --- /dev/null +++ b/16/x_/mxpi.asm @@ -0,0 +1,267 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Put image +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Move functions. +; Note: loops unrolled and optimized for CX even, no check for CX = 0. +; +subMove PROC NEAR + shr cx, 1 ; Make CX even + jc @@Odd ; Special case if odd byte +@@Loop: movsb + add si, 3 + movsb + add si, 3 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: movsb + add si, 3 + jcxz @@Exit + jmp @@Loop +subMove ENDP +; +subAnd PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + and es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + and es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subAnd ENDP +; +subOr PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + or es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + or es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subOr ENDP +; +subXor PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + xor es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + xor es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: inc di + add si, 4 + dec cx + jnz @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + inc di + add si, 4 + dec cx + jnz @@Loop + ret +subAdd ENDP + +;----------------------------------------------------------- +; +; Copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxPutImage PROC FAR + ARG Op:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Setup planes for output to VGA registers + mov cl, [ReadPlane] + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov ds, WORD PTR Image[2] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov si, WORD PTR Image[0] + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov di, [PixelOffset] +@@Loop: + push si + push di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move + mov ah, [OpInfo] ; Transparent color for subTrans + call [MoveFunction] + pop di + pop si + add si, [Width] ; Go to next image line + add di, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + rol [WritePlane], 1 + adc [PixelOffset], 0 + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxpn.asm b/16/x_/mxpn.asm new file mode 100755 index 00000000..eaaf61b4 --- /dev/null +++ b/16/x_/mxpn.asm @@ -0,0 +1,60 @@ +;----------------------------------------------------------- +; +; MXPN.ASM - Panning function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxPan + +EXTRN mxWaitDisplay : FAR +EXTRN mxStartAddress : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves the screen. +; +; Input: +; X, Y = new X, Y coordinates of view screen +; Output: +; none +; +mxPan PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov ax, [Y] + mul [mx_BytesPerLine] + mov dx, [X] + shr dx, 1 + shr dx, 1 + add ax, dx + push ax ; Push the start address + call mxWaitDisplay + call mxStartAddress + + mov dx, 03DAh ; Set the pixel pan register + in al, dx + mov dx, 03C0h + mov al, 33h + out dx, al + mov al, BYTE PTR [X] + and al, 3 + shl al, 1 + out dx, al + + xor ax, ax + .leave ARG_SIZE +mxPan ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxpp.asm b/16/x_/mxpp.asm new file mode 100755 index 00000000..fc1755a3 --- /dev/null +++ b/16/x_/mxpp.asm @@ -0,0 +1,121 @@ +;----------------------------------------------------------- +; +; MXPP.ASM - Get/put pixel functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPixel +PUBLIC mxPutPixel + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Gets a pixel. +; +; Input: +; X, Y = pixel coordinates +; Output: +; pixel color +; +mxGetPixel PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + xor ax, ax + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov bx, [Y] + cmp bx, [mx_ClipY1] + jl @@Exit + cmp bx, [mx_ClipY2] + jg @@Exit + + mov al, 04h ; Set read plane + mov ah, BYTE PTR [X] + and ah, 3 + mov dx, GDC + out dx, ax + + mov ds, [mx_VideoSegment] + mov ax, bx + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov al, ds:[si] ; Get pixel value + xor ah, ah + +@@Exit: + .pop ds, si + .leave ARG_SIZE +mxGetPixel ENDP + +;----------------------------------------------------------- +; +; Puts a pixel of the specified color. +; +; Input: +; X, Y = pixel coordinates +; Color = pixel color +; Output: +; none +; +mxPutPixel PROC FAR + ARG Color:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov ax, [Y] + cmp ax, [mx_ClipY1] + jl @@Exit + cmp ax, [mx_ClipY2] + jg @@Exit + + mov ds, [mx_VideoSegment] + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov cl, BYTE PTR [X] ; Set write plane + and cl, 3 + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[si], al + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxPutPixel ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxra.asm b/16/x_/mxra.asm new file mode 100755 index 00000000..dd8e6839 --- /dev/null +++ b/16/x_/mxra.asm @@ -0,0 +1,37 @@ +;----------------------------------------------------------- +; +; MXRA.ASM - Row address +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRowAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the row address register. +; +; Input: +; RowAddress = row size in words +; Output: +; none +; +mxRowAddress PROC FAR + ARG RowAddress:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov dx, CRTC + mov al, 13h + mov ah, [RowAddress] + out dx, ax + xor ax, ax + .leave ARG_SIZE +mxRowAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxrp.asm b/16/x_/mxrp.asm new file mode 100755 index 00000000..de820c16 --- /dev/null +++ b/16/x_/mxrp.asm @@ -0,0 +1,101 @@ +;----------------------------------------------------------- +; +; MXRP.ASM - Rotate palette function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRotatePalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Rotates the palette of the specified number of colors. +; +; Input: +; Palette = pointer to palette +; Count = number of colors to rotate +; Step = step size +; Output: +; none +; +; Note: if Step is positive palette is rotated left to right, otherwise +; right to left. +; +mxRotatePalette PROC FAR + ARG Step:WORD, \ + Count:WORD, \ + Palette:DWORD = ARG_SIZE + LOCAL Holder:BYTE:768 = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov bx, [Count] + add bx, bx + add bx, [Count] ; BX = Count*3 + + lds si, [Palette] ; DS:SI -> palette + push ss + pop es + lea di, Holder ; ES:DI -> local space + cld + + mov ax, [Step] + mov dx, ax + test ax, ax + jz @@Exit ; Nothing to do, exit + jl @@RightToLeft + +@@LeftToRight: + add ax, ax + add dx, ax ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + add si, bx + push si + mov cx, dx + rep movsb + mov es, WORD PTR Palette[2] + mov di, si + dec di ; ES:DI -> last byte of palette + pop si + dec si + mov cx, bx + std + rep movsb + push ss + pop ds + lea si, Holder + les di, [Palette] + mov cx, dx + cld + rep movsb + jmp @@Exit + +@@RightToLeft: + add ax, ax + add dx, ax + neg dx ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + mov cx, dx + rep movsb + les di, [Palette] + mov cx, bx + rep movsb + push ss + pop ds + lea si, Holder + mov cx, dx + rep movsb + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxRotatePalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxsa.asm b/16/x_/mxsa.asm new file mode 100755 index 00000000..3ebae67d --- /dev/null +++ b/16/x_/mxsa.asm @@ -0,0 +1,44 @@ +;----------------------------------------------------------- +; +; MXSA.ASM - Start address function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxStartAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Modifies the starting address of video memory. +; +; Input: +; StartAddr = new start address of video memory +; Output: +; none +; +mxStartAddress PROC FAR + ARG StartAddr:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov bx, [StartAddr] + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + + .leave ARG_SIZE +mxStartAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxsc.asm b/16/x_/mxsc.asm new file mode 100755 index 00000000..bcae45e6 --- /dev/null +++ b/16/x_/mxsc.asm @@ -0,0 +1,50 @@ +;----------------------------------------------------------- +; +; MXSC.ASM - Set color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the selected DAC register. +; +; Input: +; Index = index of color to set +; R, G, B = color components +; Output: +; none +; +mxSetColor PROC FAR + ARG B:BYTE:2, \ + G:BYTE:2, \ + R:BYTE:2, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + + mov al, [R] + out dx, al + mov al, [G] + out dx, al + mov al, [B] + out dx, al + + .pop ds, si + .leave ARG_SIZE +mxSetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxsi.asm b/16/x_/mxsi.asm new file mode 100755 index 00000000..b88d3b11 --- /dev/null +++ b/16/x_/mxsi.asm @@ -0,0 +1,317 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Stretch image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStretchImage + +EXTRN subClipBox : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Stretches and copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; NewWidth = new width of image in pixels +; NewHeight = new height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxStretchImage PROC FAR + ARG Op:WORD, \ + NewHeight:WORD, \ + NewWidth:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WidthStep:DWORD, \ + HeightStep:DWORD, \ + ImageLo:WORD, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Get width stretch factor + IF USE386 EQ TRUE + movzx edx, [Width] + xor eax, eax + movzx ebx, [NewWidth] + shl ebx, 16 + idiv ebx + mov [WidthStep], eax + ELSE + xor dx, dx ; Width stretch factor + mov ax, [Width] + mov bx, [NewWidth] + div bx + mov WORD PTR WidthStep[2], ax + xor ax, ax + div bx + mov WORD PTR WidthStep[0], ax + ENDIF +; Get height stretch factor + IF USE386 EQ TRUE + movzx edx, [Height] + xor eax, eax + movzx ebx, [NewHeight] + shl ebx, 16 + idiv ebx + mov [HeightStep], eax + ELSE + xor dx, dx + mov ax, [Height] + mov bx, [NewHeight] + div bx + mov WORD PTR HeightStep[2], ax + xor ax, ax + div bx + mov WORD PTR HeightStep[0], ax + ENDIF + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [NewWidth] + mov dx, [NewHeight] + call subClipBox + jc @@Exit ; Full clipped + mov [NewWidth], cx + mov [NewHeight], dx + sub [X], bx + sub [Y], ax + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl ; Set read plane + mov cl, bl + mov al, 00010001b + shl al, cl + mov [WritePlane], al ; Set write plane + +; Relocate image origin if previously clipped + mov ax, [Y] + test ax, ax + jz @@OriginYDone + IF USE386 EQ TRUE + shl eax, 16 + imul [HeightStep] + mov ax, [Width] + mul dx + ELSE + mov bx, ax + mul WORD PTR HeightStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR HeightStep[2] + add ax, cx + mul [Width] + ENDIF + add WORD PTR [Image], ax +@@OriginYDone: + mov ax, [X] + test ax, ax + jz @@OriginXDone + IF USE386 EQ TRUE + shl eax, 16 + imul [WidthStep] + add WORD PTR [Image], dx + ELSE + mov bx, ax + mul WORD PTR WidthStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR WidthStep[2] + add ax, cx + add WORD PTR [Image], ax + ENDIF +@@OriginXDone: + mov ax, WORD PTR HeightStep[2] + mul [Width] + mov WORD PTR HeightStep[2], ax + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + mov ds, WORD PTR Image[2] + xor ax, ax + mov [ImageLo], ax +@@Loop: + mov si, WORD PTR Image[0] ; Get pointer to image + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov cx, [NewHeight] + mov di, [PixelOffset] ; ES:DI points to video memory + mov ah, [OpInfo] ; Additional raster op info + xor bx, bx + mov dx, [mx_BytesPerLine] + call [MoveFunction] ; Draw column + inc [ReadPlane] ; Next read plane + rol [WritePlane], 1 ; Next write plane + adc [PixelOffset], 0 ; Update video offset if needed + mov dx, WORD PTR WidthStep[0] + mov ax, WORD PTR WidthStep[2] + add [ImageLo], dx + adc WORD PTR Image[0], ax ; Next image column + dec [NewWidth] + jnz @@Loop ; Repeat for all columns + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Move functions, on entry: +; AH = additional raster op info (e.g. transparent color) +; BX = 0, +; CX = pixel count, +; DX = mx_BytesPerLine. +; +subMove PROC NEAR +@@Loop: mov al, ds:[si] + mov es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subMove ENDP +; +subAnd PROC NEAR +@@Loop: mov al, ds:[si] + and es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAnd ENDP +; +subOr PROC NEAR +@@Loop: mov al, ds:[si] + or es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subOr ENDP +; +subXor PROC NEAR +@@Loop: mov al, ds:[si] + xor es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAdd ENDP + +mxStretchImage ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxsl.asm b/16/x_/mxsl.asm new file mode 100755 index 00000000..d7908855 --- /dev/null +++ b/16/x_/mxsl.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Start line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStartLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Changes the video start address to the specified line. +; +; Input: +; Line = new start line +; Output: +; none +; +mxStartLine PROC FAR + ARG Line:WORD = ARG_SIZE + .enter 0 + ASSUME ds:NOTHING + + mov ax, [Line] ; Get video offset + mul [mx_BytesPerLine] + xchg ax, bx ; Copy it into BX + +; Wait display + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + +; Set starting address + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + +; Wait retrace + mov dx, STATUS +@@2: in al,dx + test al, 08h + jz @@2 + + xor ax, ax + .leave ARG_SIZE +MX_TEXT ENDS +END diff --git a/16/x_/mxsm.asm b/16/x_/mxsm.asm new file mode 100755 index 00000000..183fba1e --- /dev/null +++ b/16/x_/mxsm.asm @@ -0,0 +1,508 @@ +;----------------------------------------------------------- +; +; MXSM.ASM - Set/change mode functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxChangeMode +PUBLIC mxGetAspect +PUBLIC mxGetScreenSize +PUBLIC mxSetMode + +PUBLIC mx_ScreenWidth +PUBLIC mx_ScreenHeight +PUBLIC mx_BytesPerLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mxSetSysClipRegion : FAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD + +mx_ScreenWidth DW ? ; Current screen width +mx_ScreenHeight DW ? +mx_AspectX DW ? ; Aspect ratio for current mode +mx_AspectY DW ? +mx_BytesPerLine DW 0 ; Bytes per line + +; +; Tables for setting video modes, sources: +; - MODEX.ASM, Matt Pritchard +; - Dr. Dobb's Journal, Michael Abrash +; - Fractint VIDEO.ASM module +; +TBL_SingleLine LABEL WORD ; CRTC + DW 04009h ; Cell height: 1 scan line + DW 00014h ; Double word mode off + DW 0E317h ; Byte mode on + DW 0 +TBL_DoubleLine LABEL WORD ; CRTC + DW 04109h ; Cell height: 2 scan lines + DW 00014h + DW 0E317h + DW 0 +TBL_Width320 LABEL WORD ; CRTC + DW 05F00h ; Horizontal total + DW 04F01h ; Horizontal displayed + DW 05002h ; Start horizontal blanking + DW 08203h ; End horizontal blanking + DW 05404h ; Start horizontal sync + DW 08005h ; End horizontal sync + DW 02813h ; Row address + DW 0 +TBL_Width360 LABEL WORD ; CRTC + DW 06B00h ; Horizontal total + DW 05901h ; Horizontal displayed + DW 05A02h ; Start horizontal blanking + DW 08E03h ; End horizontal blanking + DW 05E04h ; Start horizontal sync + DW 08A05h ; End horizontal sync + DW 02D13h ; Row address + DW 0 +TBL_Height175 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 08310h ; Start vertical sync + DW 08511h ; End vertical sync + DW 05D12h ; Vertical displayed + DW 06315h ; Start vertical blanking + DW 0BA16h ; End vertical blanking + DW 0 +TBL_Height200 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 09C10h ; Start vertical sync + DW 08E11h ; End vertical sync + DW 08F12h ; Vertical displayed + DW 09615h ; Start vertical blanking + DW 0B916h ; End vertical blanking + DW 0 +TBL_Height240 LABEL WORD ; CRTC + DW 00D06h ; Vertical total + DW 03E07h ; Overflow + DW 0EA10h ; Start vertical sync + DW 08C11h ; End vertical sync + DW 0DF12h ; Vertical displayed + DW 0E715h ; Start vertical blanking + DW 00616h ; End vertical blanking + DW 0 +TBL_Tweak400x600: + DW 07400h + DW 06301h + DW 06402h + DW 09703h + DW 06804h + DW 09505h + DW 08606h + DW 0F007h + DW 06009h + DW 0310Fh + DW 05B10h + DW 08D11h + DW 05712h + DW 03213h + DW 00014h + DW 06015h + DW 08016h + DW 0E317h + DW 0 + +TBL_320x200: + DB 63h ; 400 scan lines, 25 MHz clock + DW 6, 5 ; Aspect: 6/5 = 1.2:1 + DW 320, 200 ; Size + DW TBL_Width320, TBL_Height200, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x240: + DB 0E3h ; 400 scan lines, 25 MHz clock + DW 1, 1 ; Aspect: 1/1 = 1:1 + DW 320, 240 ; Size + DW TBL_Width320, TBL_Height240, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x400: + DB 63h ; 480 scan lines, 25 MHz clock + DW 6, 10 ; Aspect: 6/10 = 0.6:1 + DW 320, 400 ; Size + DW TBL_Width320, TBL_Height200, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_320x480: + DB 0E3h ; 480 scan lines, 25 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 320, 480 ; Size + DW TBL_Width320, TBL_Height240, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_360x200: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 20 ; Aspect: 27/20 = 1.35:1 + DW 360, 200 ; Size + DW TBL_Width360, TBL_Height200, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x240: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 8 ; Aspect: 9/8 = 1.125:1 + DW 360, 240 ; Size + DW TBL_Width360, TBL_Height240, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x400: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 40 ; Aspect: 27/40 = 0.675:1 + DW 360, 400 ; Size + DW TBL_Width360, TBL_Height200, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_360x480: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 16 ; Aspect: 9/16 = 0.5625:1 + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height240, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_320x175: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_DoubleLine, 0 + DW 819 +TBL_320x350: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_SingleLine, 0 + DW 819 +TBL_360x175: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x350: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_400x600: + DB 0E7h ; 28 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 400, 600 ; Size + DW TBL_Tweak400x600, 0 + DW 655 ; Max height + +TBL_Mode LABEL WORD + DW TBL_320x175 + DW TBL_320x200 + DW TBL_320x240 + DW TBL_320x350 + DW TBL_320x400 + DW TBL_320x480 + DW TBL_360x175 + DW TBL_360x200 + DW TBL_360x240 + DW TBL_360x350 + DW TBL_360x400 + DW TBL_360x480 + DW TBL_400x600 + +MAXVMODE EQU ($-OFFSET TBL_Mode) / 2 + +;----------------------------------------------------------- +; +; Enables 80x25 color text mode +; +subText PROC NEAR + ASSUME ds:MX_TEXT + mov ax, 0003h + int 10h ; Call BIOS set mode + + mov [mx_ScreenHeight], 0 + mov [mx_BytesPerLine], 0 + ret +subText ENDP + +;----------------------------------------------------------- +; +; Enables the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; +mxSetMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jnz @@Set ; No, handle it + + call subText ; Back to text mode + jmp @@Exit ; Exit now + +; Set video mode +@@Set: + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + +; Use BIOS to set 320x200x256 linear mode + push si ; Save SI + mov ax, 0013h + int 10h ; Use BIOS to set 320x200 linear mode + pop si ; Restore SI + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + shr ax, 1 + shr ax, 1 ; Divide by four to get bytes per line + mov [mx_BytesPerLine], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Set virtual screen and system clip region + push [mx_ScreenWidth] + push WORD PTR ds:[bx] + call mxSetSysClipRegion + +; Clear video memory + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov es, [mx_VideoSegment] + xor di, di + mov cx, 8000h + xor ax, ax + rep stosw + +@@Done: +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxSetMode ENDP + +;----------------------------------------------------------- +; +; Changes from the current mode the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; Notes: +; this function assumes that mxSetMode and mxSetVirtualScreen +; have been called first. View size is rearranged to match the +; specified mode, but video memory is not cleared. +; Differences from mxSetMode: +; - video BIOS is not called to initialize graphics; +; - row address register is not modified; +; - video memory is not cleared; +; - mx_BytesPerLine is not modified; +; - system clip region is not modified. +; +mxChangeMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jz @@Exit ; Yes, exit + + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + cmp al, 13h ; Row address register? + je @@Loop ; Yes, ignore it + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxChangeMode ENDP + +;----------------------------------------------------------- +; +; Returns the aspect ratio for the current mode. +; +; Input: +; AspectX = pointer to aspect X +; AspectY = pointer to aspect Y +; +; A rectangle of width AspectX and height AspectY looks like a square. +; +mxGetAspect PROC FAR + ARG AspectY:DWORD, \ + AspectX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [AspectX] + mov ax, [mx_AspectX] + mov ds:[si], ax + lds si, [AspectY] + mov ax, [mx_AspectY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetAspect ENDP + +;----------------------------------------------------------- +; +; Returns the current screen size. +; +; Input: +; Width = pointer to screen width +; Height = pointer to screen height +; +mxGetScreenSize PROC FAR + ARG SizeY:DWORD, \ + SizeX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [SizeX] + mov ax, [mx_ScreenWidth] + mov ds:[si], ax + lds si, [SizeY] + mov ax, [mx_ScreenHeight] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetScreenSize ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxsp.asm b/16/x_/mxsp.asm new file mode 100755 index 00000000..1d08e711 --- /dev/null +++ b/16/x_/mxsp.asm @@ -0,0 +1,57 @@ +;----------------------------------------------------------- +; +; MXSP.ASM - Set palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to set +; Count = number of color to set +; Output: +; none +; +mxSetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + lds si, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + cld + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + + .pop ds, si + .leave ARG_SIZE +mxSetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxss.asm b/16/x_/mxss.asm new file mode 100755 index 00000000..97df7366 --- /dev/null +++ b/16/x_/mxss.asm @@ -0,0 +1,72 @@ +;----------------------------------------------------------- +; +; MXSS.ASM - Split screen function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSplitScreen + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Splits the screen. +; +; Input: +; Line = scan line at which screen has to be splitted +; Output: +; none +; +mxSplitScreen PROC FAR + ARG Line:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + +; Modify the line compare value: bits 0-7 are in the Line Compare +; register (CRTC #18), bit 8 is in the Overflow Low register (CRTC #7) +; and bit 9 is in the Maximum Row Address register (CRTC #9) + mov ax, [Line] + shl ax, 1 ; Adjust line for mode "X" + mov bh, ah + mov bl, ah + and bx, 0201h + mov cl, 4 + shl bx, cl + shl bh, 1 + mov dx, CRTC +; Write bits 0-7 to line compare register + mov ah, al + mov al, 18h + out dx, ax +; Write bit 8 to overflow register + mov al, 07h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 11101111b + or ah, bl + mov al, 07h + out dx, ax +; Write bit 9 to maximum row address register + mov al, 09h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 10111111b + or ah, bh + mov al, 09h + out dx, ax + + .leave ARG_SIZE +mxSplitScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxtl.asm b/16/x_/mxtl.asm new file mode 100755 index 00000000..69900c88 --- /dev/null +++ b/16/x_/mxtl.asm @@ -0,0 +1,169 @@ +;----------------------------------------------------------- +; +; MXTL.ASM - Put tile +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutTile +PUBLIC mxTransPutTile + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + + shr cx, 1 ; Move line + rep movsw + rcl cx, 1 + rep movsb + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutTile ENDP + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; Skips over color 0. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxTransPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + +; Move one line + jcxz @@MoveLineDone +@@MoveLineLoop: + mov al, ds:[si] + test al, al + jz @@MoveLineNext + mov es:[di], al +@@MoveLineNext: + inc si + inc di + dec cx + jnz @@MoveLineLoop +@@MoveLineDone: + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxTransPutTile ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxvs.asm b/16/x_/mxvs.asm new file mode 100755 index 00000000..992eabab --- /dev/null +++ b/16/x_/mxvs.asm @@ -0,0 +1,110 @@ +;----------------------------------------------------------- +; +; MXVS.ASM - Set/get virtual screen +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetVirtualScreen +PUBLIC mxGetVirtualScreen + +EXTRN mxRowAddress : FAR +EXTRN mxSetSysClipRegion : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_CodeSegment : WORD + +mx_VirtualWidth DW ? ; Virtual screen size +mx_VirtualHeight DW ? + +;----------------------------------------------------------- +; +; Sets the virtual screen. +; +; Input: +; Width = virtual screen width +; Height = virtual screen height +; Output: +; 0 on success, else invalid parameters +; +mxSetVirtualScreen PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + +; Set DS to code segment + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, 1 ; Assume an error + cmp [Width], 320 ; Check width + jb @@Exit + push ax ; Save return code + mov dx, 0004h + xor ax, ax ; DX:AX = 256K + div [Width] ; Max height in AX + cmp [Height], ax + pop ax ; Restore return code + ja @@Exit ; Exit if bad heigth + + mov ax, [Width] + and ax, 0FFF8h ; Align to byte + mov [mx_VirtualWidth], ax + shr ax, 1 + shr ax, 1 + mov [mx_BytesPerLine], ax + shr ax, 1 + push ax + call mxRowAddress ; Set row address + mov ax, [Height] + mov [mx_VirtualHeight], ax + + push [Width] + push [Height] + call mxSetSysClipRegion + xor ax, ax + +@@Exit: + .pop ds + .leave ARG_SIZE +mxSetVirtualScreen ENDP + +;----------------------------------------------------------- +; +; Returns the current virtual screen size. +; +; Input: +; Width = pointer to virtual screen width +; Height = pointer to virtual screen height +; Output: +; none +; +mxGetVirtualScreen PROC FAR + ARG Height:DWORD, \ + Width:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + mov ax, [mx_VirtualWidth] + lds si, [Width] + mov ds:[si], ax + mov ax, [mx_VirtualHeight] + lds si, [Height] + mov ds:[si], ax + + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxGetVirtualScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxwd.asm b/16/x_/mxwd.asm new file mode 100755 index 00000000..de55208f --- /dev/null +++ b/16/x_/mxwd.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWD.ASM - Wait display function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitDisplay + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for display start. +; +mxWaitDisplay PROC FAR + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + ret +mxWaitDisplay ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxwm.asm b/16/x_/mxwm.asm new file mode 100755 index 00000000..06158859 --- /dev/null +++ b/16/x_/mxwm.asm @@ -0,0 +1,39 @@ +;----------------------------------------------------------- +; +; MXWM.ASM - Set write mode function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWriteMode + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write mode. +; +; Input: +; Mode = write mode (0,1,2,3) +; Output: +; none +; +mxWriteMode PROC FAR + ARG Mode:BYTE:2 = ARG_SIZE + .enter 0 + + mov dx, GDC + mov ah, [Mode] + and ah, 00000011b + or ah, 01000000b + mov al, 05h + out dx, ax + + .leave ARG_SIZE +mxWriteMode ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxwp.asm b/16/x_/mxwp.asm new file mode 100755 index 00000000..19ca99d0 --- /dev/null +++ b/16/x_/mxwp.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXWP.ASM - Set write/read plane functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWritePlane +PUBLIC mxReadPlane + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write plane(s). +; +; Input: +; Plane = write plane(s) to set (bit 0 enables plane 0, +; bit 1 enables plane 1 and so on, different planes +; may be selected at the same time) +; Output: +; none +; +mxWritePlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + .enter 0 + + mov ah, [Plane] + and ah, 00001111b ; Mask off unused bits + mov al, 02h + mov dx, TS + out dx, ax + + .leave ARG_SIZE +mxWritePlane ENDP + +;----------------------------------------------------------- +; +; Sets the read plane. +; +; Input: +; Plane = read plane to set (0,1,2,3) +; Output: +; none +; +mxReadPlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov al, 04h + mov ah, [Plane] + and ah, 0000011b ; Mask off unused bits + mov dx, GDC + out dx, ax + .leave ARG_SIZE +mxReadPlane ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/mxwr.asm b/16/x_/mxwr.asm new file mode 100755 index 00000000..bd29fe59 --- /dev/null +++ b/16/x_/mxwr.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWR.ASM - Wait vertical retrace function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitRetrace + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for vertical retrace start. +; +mxWaitRetrace PROC FAR + mov dx, STATUS +@@1: in al,dx + test al, 08h + jz @@1 + ret +mxWaitRetrace ENDP + +MX_TEXT ENDS +END diff --git a/16/x_/readme.txt b/16/x_/readme.txt new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/x_/readme.txt @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xlib/demo1.exe b/16/xlib/demo1.exe deleted file mode 100755 index 7d8a4d65..00000000 Binary files a/16/xlib/demo1.exe and /dev/null differ diff --git a/16/xlib/demo2.exe b/16/xlib/demo2.exe deleted file mode 100755 index d6dfd068..00000000 Binary files a/16/xlib/demo2.exe and /dev/null differ diff --git a/16/xlib/demo3.exe b/16/xlib/demo3.exe deleted file mode 100755 index ef3a06a2..00000000 Binary files a/16/xlib/demo3.exe and /dev/null differ diff --git a/16/xlib/demo4.exe b/16/xlib/demo4.exe deleted file mode 100755 index 54c567da..00000000 Binary files a/16/xlib/demo4.exe and /dev/null differ diff --git a/16/xlib/demo5.exe b/16/xlib/demo5.exe deleted file mode 100755 index 30993d2f..00000000 Binary files a/16/xlib/demo5.exe and /dev/null differ diff --git a/16/xlib/demo6.exe b/16/xlib/demo6.exe deleted file mode 100755 index 7e26f1f6..00000000 Binary files a/16/xlib/demo6.exe and /dev/null differ diff --git a/16/xlib/demo7.exe b/16/xlib/demo7.exe deleted file mode 100755 index 3762184b..00000000 Binary files a/16/xlib/demo7.exe and /dev/null differ diff --git a/16/xlib/demo8.exe b/16/xlib/demo8.exe deleted file mode 100755 index 98c480e2..00000000 Binary files a/16/xlib/demo8.exe and /dev/null differ diff --git a/16/xlib/makefile b/16/xlib/makefile index cba0dcac..d1ec5db3 100755 --- a/16/xlib/makefile +++ b/16/xlib/makefile @@ -150,6 +150,9 @@ xvsync.$(OBJ) : xvsync.asm# xvsync.inc xlib.inc model.inc xfill.$(OBJ) : xfill.asm# xfill.inc xlib.inc model.inc $(CC) -c $(CFLAGS) xfill.asm# xfill.inc xlib.inc model.inc +xbezier.$(OBJ): xbezier.asm + $(CC) -c $(CFLAGS) xbezier.asm + # #other~ # diff --git a/16/xlib/model.inc b/16/xlib/model.inc index 0aded8e9..f35b3fae 100755 --- a/16/xlib/model.inc +++ b/16/xlib/model.inc @@ -1,20 +1,22 @@ -/*;IFDEF s +IFDEF s ; DISPLAY "XLIB04 Small Model" -; .model small -;ELSE -; IFDEF c + .model small +ELSE + IFDEF c ; DISPLAY "XLIB04 Compact Model" -; .model compact -; ELSE -; IFDEF l + .model compact + ELSE + IFDEF l ; DISPLAY "XLIB04 Large Model" -; .model large -; ELSE + .model large + ELSE + IFDEF h + .model huge + ELSE ; DISPLAY "WARNING: Model was not defined at the command line." ; DISPLAY " Using default small model ie /ds " ; DISPLAY " Include in TASM commandline either /ds, /dc or /dl" -;; .model small -; ENDIF -; ENDIF -;ENDIF -*/ + .model small + ENDIF + ENDIF +ENDIF diff --git a/16/xlib/xbmtools.asm b/16/xlib/xbmtools.asm index f39c9a32..490b2635 100755 --- a/16/xlib/xbmtools.asm +++ b/16/xlib/xbmtools.asm @@ -42,7 +42,7 @@ COMMENT $ $ -LOCALS +.LOCALS .8086 include model.inc diff --git a/16/xlib/xfileio.asm b/16/xlib/xfileio.asm index 40a07775..253e237c 100755 --- a/16/xlib/xfileio.asm +++ b/16/xlib/xfileio.asm @@ -430,4 +430,3 @@ _f_filelength endp end - diff --git a/16/xlib/xlib.inc b/16/xlib/xlib.inc index 3dbfa758..e352f3cf 100755 --- a/16/xlib/xlib.inc +++ b/16/xlib/xlib.inc @@ -19,12 +19,12 @@ ; -;.LOCALS +;.global ;.8086 ; First lets find out what memory model to use - -include model.inc +;.model huge +;include model.inc AC_INDEX equ 03c0h ;Attribute controller index register @@ -162,5 +162,3 @@ WaitNotVsync2: global _VsyncPaletteStart :word global _VsyncPaletteCount :word global _VsyncPaletteBuffer :byte - - diff --git a/16/xlib/xline.asm b/16/xlib/xline.asm index 6c9c5c56..910c1fc9 100755 --- a/16/xlib/xline.asm +++ b/16/xlib/xline.asm @@ -26,9 +26,10 @@ ModeXAddr macro mov dx,[_ScrnLogicalByteWidth] mul dx pop dx - shr bx,2 + shr bx,1 + shr bx,1 add bx,ax - add bx,[PgOffs] + add bx,[bp+14] and cl,3 endm @@ -44,7 +45,7 @@ ModeXAddr macro ; _x_line proc -ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word +;ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk push bp ; Set up stack frame mov bp,sp @@ -60,8 +61,8 @@ LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk ; check for vertical line mov si,[_ScrnLogicalByteWidth] - mov cx,[x2] - sub cx,[x1] + mov cx,[bp+8] + sub cx,[bp+4] jz VertLine ; force x1 < x2 @@ -70,19 +71,19 @@ LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk neg cx - mov bx,[x2] - xchg bx,[x1] - mov [x2],bx + mov bx,[bp+8] + xchg bx,[bp+4] + mov [bp+8],bx - mov bx,[y2] - xchg bx,[y1] - mov [y2],bx + mov bx,[bp+10] + xchg bx,[bp+6] + mov [bp+10],bx ; calc dy = abs(y2 - y1) L01: - mov bx,[y2] - sub bx,[y1] + mov bx,[bp+10] + sub bx,[bp+6] jnz short skip jmp HorizLine skip: jns L03 @@ -113,14 +114,17 @@ L04: ; calc first pixel address push cx - mov ax,[y1] - mov bx,[x1] + mov ax,[bp+6] + mov bx,[bp+4] ModeXAddr mov di,bx mov al,1 shl al,cl mov ah,al ; duplicate nybble - shl al,4 + shl al,1 + shl al,1 + shl al,1 + shl al,1 add ah,al mov bl,ah pop cx @@ -130,8 +134,8 @@ L04: ; routine for verticle lines VertLine: - mov ax,[y1] - mov bx,[y2] + mov ax,[bp+6] + mov bx,[bp+10] mov cx,bx sub cx,ax jge L31 @@ -140,7 +144,7 @@ VertLine: L31: inc cx - mov bx,[x1] + mov bx,[bp+4] push cx ModeXAddr @@ -149,7 +153,7 @@ L31: mov al,MAP_MASK out dx,ax pop cx - mov ax, word ptr [Color] + mov ax, word ptr [bp+12] ; draw the line @@ -164,15 +168,15 @@ L32: HorizLine: push ds - mov ax,[y1] - mov bx,[x1] + mov ax,[bp+6] + mov bx,[bp+4] ModeXAddr mov di,bx ; set dl = first byte mask mov dl,00fh shl dl,cl - mov cx,[x2] ; set dh = last byte mask + mov cx,[bp+8] ; set dh = last byte mask and cl,3 mov dh,00eh shl dh,cl @@ -180,17 +184,19 @@ HorizLine: ; determine byte offset of first and last pixel in line - mov ax,[x2] - mov bx,[x1] + mov ax,[bp+8] + mov bx,[bp+4] - shr ax,2 ; set ax = last byte column - shr bx,2 ; set bx = first byte column + shr ax,1 ; set ax = last byte column + shr bx,1 ; set bx = first byte column + shr ax,1 ; set ax = last byte column + shr bx,1 ; set bx = first byte column mov cx,ax ; cx = ax - bx sub cx,bx mov ax,dx ; mov end byte masks to ax mov dx,SC_INDEX ; setup dx for VGA outs - mov bx, [Color] + mov bx, [bp+12] ; set pixels in leftmost byte of line @@ -231,7 +237,7 @@ L44: LoSlopeLine: mov al,MAP_MASK - mov bh,byte ptr [Color] + mov bh,byte ptr [bp+12] L10: mov ah,bl @@ -283,7 +289,7 @@ HiSlopeLine: mov al,MAP_MASK L21: out dx,ax push ax - mov ax,[Color] + mov ax,[bp+12] mov es:[di],al pop ax add di,bx @@ -314,4 +320,3 @@ Lexit: _x_line endp end - \ No newline at end of file diff --git a/16/xlib/xmain.asm b/16/xlib/xmain.asm index a8fd4184..cdb174fd 100755 --- a/16/xlib/xmain.asm +++ b/16/xlib/xmain.asm @@ -22,19 +22,18 @@ ; and tripple buffering - Tore Jahn Bastiansen ; (toreba@ifi.uio.no) for the ;----------------------------------------------------------------------- - - include xlib.inc include xmain.inc - .data + _DATA SEGMENT WORD PUBLIC USE16 'DATA' +;.data ; Mode X CRTC register tweaks for various resolutions -LABEL X256Y200 word +X256Y200 LABEL word db 0e3h ; dot clock db 8 ; Number of CRTC Registers to update dw 05f00h ; horz total @@ -49,7 +48,7 @@ LABEL X256Y200 word dw 200 -LABEL X256Y240 word +X256Y240 label word db 0e3h ; dot clock db 16 ; Number of CRTC Registers to update dw 05f00h ; horz total @@ -157,7 +156,7 @@ X376Y282 label word dw 376 dw 282 -LABEL X256Y400 word +X256Y400 label word db 0e3h ; dot clock db 8 ; Number of CRTC Registers to update dw 05f00h ; horz total @@ -173,7 +172,7 @@ LABEL X256Y400 word dw 400 -LABEL X256Y480 word +X256Y480 label word db 0e3h ; dot clock db 16 ; Number of CRTC Registers to update dw 05f00h ; horz total @@ -439,6 +438,9 @@ PARAM_COUNT equ ($-PARAMS) DoubleScanFlag db ? ; Flag to indicate double scanned mode +_DATA ENDS + + .code ;------------------------------------------------------------------------- @@ -459,7 +461,9 @@ SetLogicalScrWidth proc mov ax,bx ; no - set logical width = physical @@ValidLogicalWidth: - shr ax,3 + shr ax,1 + shr ax,1 + shr ax,1 out dx,al ; The EXACT logical pixel width may not have been possible since @@ -472,10 +476,12 @@ SetLogicalScrWidth proc mov [_RightClip],ax ; Set default Right clip column ; screen sub ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position - shl ax,2 ; of physical screen in virtual + shl ax,1 ; of physical screen in virtual + shl ax,1 ; of physical screen in virtual mov [_MaxScrollX],ax ; screen in pixels mov ax,bx ; set ax to byte width of virt scrn - shl ax,2 ; convert to pixels + shl ax,1 ; convert to pixels + shl ax,1 ; convert to pixels mov [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width mov cx,ax ; save ax (return value) @@ -550,7 +556,7 @@ clear_vram endp ; parts adapted from M. Abrash code. ;------------------------------------------------------------------------ _x_set_mode proc - ARG mode:word,logicalscrwidth:word + ;;arg mode:word,logicalscrwidth:word push bp ;preserve caller's stack frame mov bp,sp @@ -565,7 +571,7 @@ _x_set_mode proc mov cx,PARAM_COUNT rep stosb - mov cx,[mode] + mov cx,[BP+4] cmp cx,LAST_X_MODE ; have we selected a valid mode jle @@ValidMode ; Yes ! @@ -657,7 +663,8 @@ _x_set_mode proc mov [_SplitScrnScanLine],ax ; No splitscrn == ; splitscrn=PhysicalscrnHeight mov bx,ax ; Copy width for later use - shr ax,2 ; Convert to byte width + shr ax,1 ; Convert to byte width + shr ax,1 ; Convert to byte width mov [_ScrnPhysicalByteWidth],ax ; Store for later use lodsw ; Load Screen Phys. Height mov [_ScrnPhysicalHeight],ax ; Store for later use @@ -665,7 +672,7 @@ _x_set_mode proc ; Mode X is set, now set the required logical page width. - mov cx,[logicalscrwidth] + mov cx,[BP+6] call SetLogicalScrWidth @@ -687,10 +694,10 @@ _x_set_mode endp ; Written by Themie Gouthas ;---------------------------------------------------------------------- _x_select_default_plane proc -ARG Plane:byte + ;arg Plane:byte push bp mov bp,sp ; set up stack frame - mov cl,byte ptr [Plane] + mov cl,byte ptr [bp+4] ; SELECT WRITE PLANE and cl,011b ;CL = plane @@ -727,7 +734,7 @@ _x_select_default_plane endp ;---------------------------------------------------------------------- _x_set_splitscreen proc - ARG Line:word + ;arg Line:word push bp mov bp,sp ; set up stack frame push si @@ -769,7 +776,7 @@ _x_set_splitscreen proc mov [_PhysicalStartPixelX],ax ; offset within virtual screen mov [_PhysicalStartY],ax mov [_SplitScrnActive],TRUE - mov ax,[Line] + mov ax,[bp+4] jns @@NotNeg ; Check that Split Scrn start scan line is +ve mov ax,0 ; Since -ve set to 0 @@ -804,7 +811,10 @@ _x_set_splitscreen proc mov ah,bh and ah,1 - shl ah,4 + shl ah,1 + shl ah,1 + shl ah,1 + shl ah,1 mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split out dx,al ; screen scan line, inc dx ; So using readability of VGA registers @@ -816,7 +826,9 @@ _x_set_splitscreen proc dec dx mov ah,bh and ah,2 - ror ah,3 + ror ah,1 + ror ah,1 + ror ah,1 mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register = out dx,al ; Bit 9 of split screen scan line inc dx ; As we did before, update the apropriate @@ -846,9 +858,9 @@ _x_set_splitscreen proc mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height cmp ax,[_BottomClip] - jle @@BottomClipOK ; Adjust Clip Rectangle if necessary + jle @@BottomClipOK2 ; Adjust Clip Rectangle if necessary mov [_BottomClip],ax -@@BottomClipOK: +@@BottomClipOK2: sub ax,[_SplitScrnScanLine] ; Update the maximum Y position of mov [_MaxScrollY],ax ; Physical screen in logical screen @@ -875,14 +887,14 @@ _x_set_splitscreen endp ;------------------------------------------------------------------------ _x_page_flip proc - ARG x:word,y:word + ;arg x:word,y:word push bp ;preserve caller's stack frame mov bp,sp ;point to local stack frame push si - mov si,[x] + mov si,[bp+4] mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment - mov cx,[y] + mov cx,[bp+6] mul cx ; for Y cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ? je @@DoubleBuffer @@ -931,14 +943,14 @@ _x_page_flip endp ; Parts addapted from M. Abrash code published in DDJ Mag. ;------------------------------------------------------------------------ _x_set_start_addr proc - ARG x:word,y:word + ;arg x:word,y:word push bp mov bp,sp push si - mov si,[x] + mov si,[bp+4] mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment - mov cx,[y] ; for Y + mov cx,[bp+6] ; for Y mul cx cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ? je @@PageResolution @@ -958,7 +970,8 @@ PageFlipEntry2: @@AddColumn: mov cx,si - shr cx,2 + shr cx,1 + shr cx,1 mov [_PhysicalStartByteX],cx add ax,cx ; add the column offset for X mov bh,al ; setup CRTC start addr regs and @@ -1052,14 +1065,14 @@ _x_hide_splitscreen proc cmp [_SplitScrnActive],TRUE je @@SplitScreenEnabled -@@error: +@@error0: mov [_ErrorValue],ERROR pop bp ret @@SplitScreenEnabled: cmp [_CurrXMode],4 ; Do nothing for Modes > 2 - jg @@error + jg @@error0 mov bx,[_ScrnPhysicalHeight] mov ax,[_ScrnLogicalHeight] @@ -1069,10 +1082,10 @@ _x_hide_splitscreen proc mov [_SplitScrnVisibleHeight],ax or [DoubleScanFlag],0 - jz @@NotDoubleScanned + jz @@NotDoubleScanned0 shl bx,1 dec bx -@@NotDoubleScanned: +@@NotDoubleScanned0: ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes ;shl bx,cl @@ -1086,7 +1099,10 @@ _x_hide_splitscreen proc mov ah,bh and ah,1 - shl ah,4 + shl ah,1 + shl ah,1 + shl ah,1 + shl ah,1 mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split out dx,al ; screen scan line, inc dx ; So using readability of VGA registers @@ -1098,7 +1114,9 @@ _x_hide_splitscreen proc dec dx mov ah,bh and ah,2 - ror ah,3 + ror ah,1 + ror ah,1 + ror ah,1 mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register = out dx,al ; Bit 9 of split screen scan line inc dx ; As we did before, update the apropriate @@ -1108,7 +1126,7 @@ _x_hide_splitscreen proc out dx,al sti ; Registers are set, so interrupts are safe -@@done: +@@done0: mov [_ErrorValue],OK pop bp @@ -1140,16 +1158,16 @@ _x_show_splitscreen proc mov bp,sp cmp [_SplitScrnActive],TRUE - je @@SplitScreenEnabled + je @@SplitScreenEnabled0 -@@error: +@@error1: mov [_ErrorValue],ERROR pop bp ret -@@SplitScreenEnabled: +@@SplitScreenEnabled0: cmp [_CurrXMode],4 ; Do nothing for Modes > 2 - jg @@error + jg @@error1 mov bx,[_SplitScrnScanLine] mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y @@ -1161,10 +1179,10 @@ _x_show_splitscreen proc mov [_SplitScrnVisibleHeight],ax or [DoubleScanFlag],0 - jz @@NotDoubleScanned + jz @@NotDoubleScanned1 shl bx,1 dec bx -@@NotDoubleScanned: +@@NotDoubleScanned1: ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes ;shl bx,cl WaitVsyncStart ; wait for vertical retrace @@ -1177,7 +1195,10 @@ _x_show_splitscreen proc mov ah,bh and ah,1 - shl ah,4 + shl ah,1 + shl ah,1 + shl ah,1 + shl ah,1 mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split out dx,al ; screen scan line, inc dx ; So using readability of VGA registers @@ -1189,7 +1210,9 @@ _x_show_splitscreen proc dec dx mov ah,bh and ah,2 - ror ah,3 + ror ah,1 + ror ah,1 + ror ah,1 mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register = out dx,al ; Bit 9 of split screen scan line inc dx ; As we did before, update the apropriate @@ -1199,7 +1222,7 @@ _x_show_splitscreen proc out dx,al sti ; Registers are set, so interrupts are safe -@@Done: +@@Done1: mov [_ErrorValue],0 pop bp ret @@ -1229,24 +1252,24 @@ _x_show_splitscreen endp _x_adjust_splitscreen proc - ARG ScanLine + ;arg ScanLine push bp mov bp,sp cmp [_SplitScrnActive],TRUE - je @@SplitScreenEnabled + je @@SplitScreenEnabled1 -@@error: +@@error2: mov [_ErrorValue],ERROR pop bp ret -@@SplitScreenEnabled: +@@SplitScreenEnabled1: cmp [_CurrXMode],4 ; Do nothing for Modes > 2 - jg @@error - mov bx,[ScanLine] ; Is the required starting scan line + jg @@error2 + mov bx,[bp+4] ; Is the required starting scan line cmp bx,[_SplitScrnScanLine] ; valid ? - js @@Done ; No - Then do nothing + js @@Done2 ; No - Then do nothing @@ValidScanLine: @@ -1259,10 +1282,10 @@ _x_adjust_splitscreen proc mov [_SplitScrnVisibleHeight],ax or [DoubleScanFlag],0 - jz @@NotDoubleScanned + jz @@NotDoubleScanned2 shl bx,1 dec bx -@@NotDoubleScanned: +@@NotDoubleScanned2: ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes ;shl bx,cl @@ -1277,7 +1300,10 @@ _x_adjust_splitscreen proc mov ah,bh and ah,1 - shl ah,4 + shl ah,1 + shl ah,1 + shl ah,1 + shl ah,1 mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split out dx,al ; screen scan line, inc dx ; So using readability of VGA registers @@ -1289,7 +1315,9 @@ _x_adjust_splitscreen proc dec dx mov ah,bh and ah,2 - ror ah,3 + ror ah,1 + ror ah,1 + ror ah,1 mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register = out dx,al ; Bit 9 of split screen scan line inc dx ; As we did before, update the apropriate @@ -1298,7 +1326,7 @@ _x_adjust_splitscreen proc or al,ah out dx,al sti ; Registers are set, so interrupts are safe -@@Done: +@@Done2: mov [_ErrorValue],OK pop bp ret @@ -1330,7 +1358,7 @@ _x_adjust_splitscreen endp _x_set_doublebuffer proc - ARG PageHeight:word + ;arg PageHeight:word push bp mov bp,sp @@ -1346,7 +1374,7 @@ _x_set_doublebuffer proc mov ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to shr ax,1 ; _ScrnLogicalHeight / 2 - mov bx,[PageHeight] ; Is the require D.B. Page Height + mov bx,[bp+4] ; Is the require D.B. Page Height cmp ax,bx ; > the Maximum D.B. Page Height ? js @@InvalidHeight ; no - jump @@ -1357,9 +1385,9 @@ _x_set_doublebuffer proc mov [_ScrnLogicalHeight],ax ; Update logical screen height to ; reflect the height of a D.B. page cmp ax,[_BottomClip] - jle @@BottomClipOK ; Adjust Clip Rectangle if necessary + jle @@BottomClipOK0 ; Adjust Clip Rectangle if necessary mov [_BottomClip],ax -@@BottomClipOK: +@@BottomClipOK0: push ax mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second mov cx,ax ; D.B. Page in video ram @@ -1410,40 +1438,40 @@ _x_set_doublebuffer endp ;------------------------------------------------------------------------ _x_set_tripplebuffer proc - ARG PageHeight:word + ;arg PageHeight:word push bp mov bp,sp cmp [_DoubleBufferActive],0 - jne @@Error + jne @@Error3 cmp [_TrippleBufferActive],0 - je @@OkToContinue -@@Error: + je @@OkToContinue3 +@@Error3: mov [_ErrorValue],ERROR pop bp ret -@@OkToContinue: +@@OkToContinue3: mov [_VisiblePageIdx],0 ; Set visible Page to 0 mov ax,[_ScrnLogicalHeight] ; Set Maximum T.B. Page height to mov bx,3 xor dx,dx idiv bx ; _ScrnLogicalHeight / 3 - mov bx,[PageHeight] ; Is the require T.B. Page Height + mov bx,[bp+4] ; Is the require T.B. Page Height cmp ax,bx ; > the Maximum T.B. Page Height ? - js @@InvalidHeight ; no - jump + js @@InvalidHeight0 ; no - jump mov ax,bx ; yes - Set the T.B. Page height to ; to the maximum allowed. -@@InvalidHeight: +@@InvalidHeight0: mov [_ScrnLogicalHeight],ax ; Update logical screen height to ; reflect the height of a T.B. page cmp ax,[_BottomClip] - jle @@BottomClipOK ; Adjust Clip Rectangle if necessary + jle @@BottomClipOK1 ; Adjust Clip Rectangle if necessary mov [_BottomClip],ax -@@BottomClipOK: +@@BottomClipOK1: push ax mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second mov cx,ax ; D.B. Page in video ram @@ -1489,19 +1517,19 @@ _x_set_tripplebuffer endp ;------------------------------------------------------------------------ _x_set_cliprect proc -ARG left:word,top:word,right:word,bottom:word +;arg left:word,top:word,right:word,bottom:word push bp mov bp,sp - mov ax,[left] - mov bx,[right] + mov ax,[bp+4] + mov bx,[bp+8] cmp bx,ax jns @@CorrectXOrder xchg bx,ax @@CorrectXOrder: mov [_LeftClip],ax mov [_RightClip],bx - mov ax,[top] - mov bx,[bottom] + mov ax,[bp+6] + mov bx,[bp+10] cmp bx,ax jns @@CorrectYOrder xchg bx,ax @@ -1536,4 +1564,4 @@ _x_wait_vsync proc _x_wait_vsync endp - end +end diff --git a/16/xlib/xmain.inc b/16/xlib/xmain.inc index 44b40fc2..4b1f4410 100755 --- a/16/xlib/xmain.inc +++ b/16/xlib/xmain.inc @@ -26,6 +26,6 @@ global _x_show_splitscreen :proc global _x_adjust_splitscreen :proc global _x_set_doublebuffer :proc - global _x_set_tripplebuffer :proc + global _x_set_tripplebuffer :proc global _x_set_cliprect :proc - global _x_wait_vsync :proc \ No newline at end of file + global _x_wait_vsync :proc diff --git a/16/xlib/xpal.asm b/16/xlib/xpal.asm index 558f2665..a27155dc 100755 --- a/16/xlib/xpal.asm +++ b/16/xlib/xpal.asm @@ -65,18 +65,18 @@ include xpal.inc ; Written by Themie Gouthas ;---------------------------------------------------------------------- _x_get_pal_struc proc -ARG PalBuff:dword,NumColors:word,StartColor:word +;ARG PalBuff:dword,NumColors:word,StartColor:word push bp ; Set up stack frame mov bp,sp push di push si cld - les di,dword ptr [PalBuff] ; Point es:di to palette buffer - mov si,[StartColor] ; Store the Start Colour + les di,dword ptr [bp+4] ; Point es:di to palette buffer + mov si,[bp+10] ; Store the Start Colour mov ax,si stosb - mov dx,[NumColors] ; Store the Number of Colours + mov dx,[bp+8] ; Store the Number of Colours mov al,dl stosb @@ -100,16 +100,16 @@ _x_get_pal_struc endp ; Written by Themie Gouthas ;---------------------------------------------------------------------- _x_get_pal_raw proc -ARG PalBuff:dword,NumColors:word,StartColor:word +;ARG PalBuff:dword,NumColors:word,StartColor:word push bp ; Set up stack frame mov bp,sp push di push si - les di,dword ptr [PalBuff] ; Point es:di to palette buffer + les di,dword ptr [bp+4] ; Point es:di to palette buffer - mov si,[StartColor] - mov cx,[NumColors] + mov si,[bp+10] + mov cx,[bp+8] ReadPalEntry: cld diff --git a/16/xlib/xpoint.asm b/16/xlib/xpoint.asm index f6bed961..7b7dc910 100755 --- a/16/xlib/xpoint.asm +++ b/16/xlib/xpoint.asm @@ -34,21 +34,21 @@ include xpoint.inc ; _x_put_pix proc - ARG X:word,Y:word,PgOfs:word,Color:word + ;ARG X:word,Y:word,PgOfs:word,Color:word push bp ;preserve caller's stack frame mov bp,sp ;point to local stack frame mov ax,[_ScrnLogicalByteWidth] - mul [Y] ;offset of pixel's scan line in page - mov bx,[X] + mul [BP+6] ;offset of pixel's scan line in page + mov bx,[BP+4] shr bx,1 ;X/4 = offset of pixel in scan line shr bx,1 ;X/4 = offset of pixel in scan line add bx,ax ;offset of pixel in page - add bx,[PgOfs] ;offset of pixel in display memory + add bx,[BP+8] ;offset of pixel in display memory mov ax,SCREEN_SEG mov es,ax ;point ES:BX to the pixel's address - mov cl,byte ptr [X] + mov cl,byte ptr [BP+4] and cl,011b ;CL = pixel's plane mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg shl ah,cl ;set only the bit for the pixel's @@ -56,7 +56,7 @@ _x_put_pix proc mov dx,SC_INDEX ;set the Map Mask to enable only the out dx,ax ; pixel's plane - mov al,byte ptr [Color] + mov al,byte ptr [BP+10] mov es:[bx],al ;draw the pixel in the desired color pop bp ;restore caller's stack frame @@ -74,21 +74,21 @@ _x_put_pix endp _x_get_pix proc - ARG x:word,y:word,PageBase:word + ;ARG x:word,y:word,PageBase:word push bp ;preserve caller's stack frame mov bp,sp ;point to local stack frame mov ax,[_ScrnLogicalByteWidth] - mul [Y] ;offset of pixel's scan line in page - mov bx,[X] + mul [bp+6] ;offset of pixel's scan line in page + mov bx,[bp+4] shr bx,1 shr bx,1 ;X/4 = offset of pixel in scan line add bx,ax ;offset of pixel in page - add bx,[PageBase] ;offset of pixel in display memory + add bx,[bp+8] ;offset of pixel in display memory mov ax,SCREEN_SEG mov es,ax ;point ES:BX to the pixel's address - mov ah,byte ptr [X] + mov ah,byte ptr [bp+4] and ah,011b ;AH = pixel's plane mov al,READ_MAP ;AL = index in GC of the Read Map reg mov dx,GC_INDEX ;set the Read Map to read the pixel's diff --git a/16/xw/default.fnt b/16/xw/default.fnt new file mode 100755 index 00000000..12eb22cb --- /dev/null +++ b/16/xw/default.fnt @@ -0,0 +1,260 @@ +; +; MODEX library default font +; Copyright (c) 1993-1994 by Alessandro Scotti +; + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0 + DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1 + DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2 + DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3 + DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4 + DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5 + DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6 + DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7 + DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8 + DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9 + DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10 + DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11 + DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12 + DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13 + DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14 + DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15 + DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16 + DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17 + DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18 + DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19 + DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20 + DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21 + DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22 + DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23 + DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24 + DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25 + DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26 + DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27 + DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28 + DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29 + DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30 + DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; + DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; ! + DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; " + DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; # + DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $ + DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; % + DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; & + DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; ' + DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; ( + DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; ) + DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; * + DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; + + DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; , + DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; - + DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; . + DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; / + DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0 + DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1 + DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2 + DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3 + DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4 + DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5 + DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6 + DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7 + DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8 + DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9 + DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; : + DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ; + DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; < + DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; = + DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; > + DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ? + DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @ + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A + DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B + DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C + DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F + DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G + DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H + DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I + DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J + DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K + DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L + DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M + DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N + DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O + DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P + DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q + DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R + DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S + DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T + DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U + DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V + DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W + DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X + DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y + DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z + DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [ + DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \ + DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ] + DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^ + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _ + DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; ` + DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a + DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b + DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c + DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d + DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e + DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g + DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h + DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i + DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j + DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k + DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l + DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m + DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n + DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o + DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q + DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r + DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s + DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t + DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u + DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v + DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w + DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x + DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y + DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z + DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; { + DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; | + DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; } + DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~ + DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ;  + DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128 + DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129 + DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130 + DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131 + DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132 + DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133 + DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134 + DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135 + DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136 + DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137 + DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138 + DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139 + DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140 + DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141 + DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142 + DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143 + DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144 + DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145 + DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146 + DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147 + DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148 + DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149 + DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150 + DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151 + DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152 + DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153 + DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154 + DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155 + DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156 + DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157 + DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158 + DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159 + DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160 + DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161 + DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162 + DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163 + DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164 + DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165 + DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166 + DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167 + DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168 + DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169 + DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170 + DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171 + DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172 + DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173 + DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174 + DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175 + DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176 + DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177 + DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178 + DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179 + DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180 + DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181 + DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182 + DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183 + DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184 + DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185 + DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186 + DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187 + DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188 + DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189 + DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190 + DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191 + DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192 + DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193 + DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194 + DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195 + DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196 + DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197 + DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198 + DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199 + DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200 + DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201 + DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202 + DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203 + DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204 + DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205 + DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206 + DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207 + DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208 + DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209 + DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210 + DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211 + DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212 + DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213 + DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214 + DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215 + DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216 + DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217 + DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218 + DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219 + DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220 + DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221 + DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222 + DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223 + DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224 + DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225 + DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226 + DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227 + DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228 + DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229 + DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230 + DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231 + DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232 + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233 + DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234 + DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235 + DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236 + DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237 + DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238 + DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239 + DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240 + DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241 + DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242 + DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243 + DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244 + DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245 + DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246 + DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247 + DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248 + DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249 + DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250 + DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251 + DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252 + DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253 + DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255 diff --git a/16/xw/makefile b/16/xw/makefile new file mode 100755 index 00000000..96d1c081 --- /dev/null +++ b/16/xw/makefile @@ -0,0 +1,132 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +!ifdef __LINUX__ +REMOVECOMMAND=rm -f +COPYCOMMAND=cp -f +DIRSEP=/ +OBJ=o +!else +REMOVECOMMAND=del +COPYCOMMAND=copy /y +DIRSEP=\ +OBJ=obj +!endif +LIBINCS = modex.def + +LIBOBJS = mxbb.$(OBJ) mxcc.$(OBJ) mxcg.$(OBJ) mxcl.$(OBJ) mxcr.$(OBJ) mxfb.$(OBJ) mxfp.$(OBJ) mxgc.$(OBJ) mxgi.$(OBJ) mxgm.$(OBJ) mxgp.$(OBJ) mxgv.$(OBJ) mxhl.$(OBJ) mxit.$(OBJ) mxll.$(OBJ) mxln.$(OBJ) mxot.$(OBJ) mxpb.$(OBJ) mxpf.$(OBJ) mxpg.$(OBJ) mxpi.$(OBJ) mxpn.$(OBJ) mxpp.$(OBJ) mxra.$(OBJ) mxrp.$(OBJ) mxsa.$(OBJ) mxsc.$(OBJ) mxsi.$(OBJ) mxsl.$(OBJ) mxsm.$(OBJ) mxsp.$(OBJ) mxss.$(OBJ) mxtl.$(OBJ) mxvs.$(OBJ) mxwd.$(OBJ) mxwm.$(OBJ) mxwp.$(OBJ) mxwr.$(OBJ) + +# +# ASM compiler +# +ASMC =wasm +ASMO =-mh -0 + +# +# PAS compiler +# +#PASC = tpc +#PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = wlib + +# .asm.obj: +# $(ASMC) $(ASMO) $< + +mxbb.$(OBJ): mxbb.asm + $(ASMC) $(ASMO) mxbb.asm +mxcc.$(OBJ): mxcc.asm + $(ASMC) $(ASMO) mxcc.asm +mxcg.$(OBJ): mxcg.asm + $(ASMC) $(ASMO) mxcg.asm +mxcl.$(OBJ): mxcl.asm + $(ASMC) $(ASMO) mxcl.asm +mxcr.$(OBJ): mxcr.asm + $(ASMC) $(ASMO) mxcr.asm +mxfb.$(OBJ): mxfb.asm + $(ASMC) $(ASMO) mxfb.asm +mxfp.$(OBJ): mxfp.asm + $(ASMC) $(ASMO) mxfp.asm +mxgc.$(OBJ): mxgc.asm + $(ASMC) $(ASMO) mxgc.asm +mxgi.$(OBJ): mxgi.asm + $(ASMC) $(ASMO) mxgi.asm +mxgm.$(OBJ): mxgm.asm + $(ASMC) $(ASMO) mxgm.asm +mxgp.$(OBJ): mxgp.asm + $(ASMC) $(ASMO) mxgp.asm +mxgv.$(OBJ): mxgv.asm + $(ASMC) $(ASMO) mxgv.asm +mxhl.$(OBJ): mxhl.asm + $(ASMC) $(ASMO) mxhl.asm +mxit.$(OBJ): mxit.asm + $(ASMC) $(ASMO) mxit.asm +mxll.$(OBJ): mxll.asm + $(ASMC) $(ASMO) mxll.asm +mxln.$(OBJ): mxln.asm + $(ASMC) $(ASMO) mxln.asm +mxot.$(OBJ): mxot.asm + $(ASMC) $(ASMO) mxot.asm +mxpb.$(OBJ): mxpb.asm + $(ASMC) $(ASMO) mxpb.asm +mxpf.$(OBJ): mxpf.asm + $(ASMC) $(ASMO) mxpf.asm +mxpg.$(OBJ): mxpg.asm + $(ASMC) $(ASMO) mxpg.asm +mxpi.$(OBJ): mxpi.asm + $(ASMC) $(ASMO) mxpi.asm +mxpn.$(OBJ): mxpn.asm + $(ASMC) $(ASMO) mxpn.asm +mxpp.$(OBJ): mxpp.asm + $(ASMC) $(ASMO) mxpp.asm +mxra.$(OBJ): mxra.asm + $(ASMC) $(ASMO) mxra.asm +mxrp.$(OBJ): mxrp.asm + $(ASMC) $(ASMO) mxrp.asm +mxsa.$(OBJ): mxsa.asm + $(ASMC) $(ASMO) mxsa.asm +mxsc.$(OBJ): mxsc.asm + $(ASMC) $(ASMO) mxsc.asm +mxsi.$(OBJ): mxsi.asm + $(ASMC) $(ASMO) mxsi.asm +mxsl.$(OBJ): mxsl.asm + $(ASMC) $(ASMO) mxsl.asm +mxsm.$(OBJ): mxsm.asm + $(ASMC) $(ASMO) mxsm.asm +mxsp.$(OBJ): mxsp.asm + $(ASMC) $(ASMO) mxsp.asm +mxss.$(OBJ): mxss.asm + $(ASMC) $(ASMO) mxss.asm +mxtl.$(OBJ): mxtl.asm + $(ASMC) $(ASMO) mxtl.asm +mxvs.$(OBJ): mxvs.asm + $(ASMC) $(ASMO) mxvs.asm +mxwd.$(OBJ): mxwd.asm + $(ASMC) $(ASMO) mxwd.asm +mxwm.$(OBJ): mxwm.asm + $(ASMC) $(ASMO) mxwm.asm +mxwp.$(OBJ): mxwp.asm + $(ASMC) $(ASMO) mxwp.asm +mxwr.$(OBJ): mxwr.asm + $(ASMC) $(ASMO) mxwr.asm + +all: $(LIBOBJS) modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw/makefile.bcc b/16/xw/makefile.bcc new file mode 100755 index 00000000..d3ad8b71 --- /dev/null +++ b/16/xw/makefile.bcc @@ -0,0 +1,81 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +LIBINCS = MODEX.DEF + +LIBOBJS = MXBB.OBJ \ + MXCC.OBJ \ + MXCG.OBJ \ + MXCL.OBJ \ + MXCR.OBJ \ + MXFB.OBJ \ + MXFP.OBJ \ + MXGC.OBJ \ + MXGI.OBJ \ + MXGM.OBJ \ + MXGP.OBJ \ + MXGV.OBJ \ + MXHL.OBJ \ + MXIT.OBJ \ + MXLL.OBJ \ + MXLN.OBJ \ + MXOT.OBJ \ + MXPB.OBJ \ + MXPF.OBJ \ + MXPG.OBJ \ + MXPI.OBJ \ + MXPN.OBJ \ + MXPP.OBJ \ + MXRA.OBJ \ + MXRP.OBJ \ + MXSA.OBJ \ + MXSC.OBJ \ + MXSI.OBJ \ + MXSL.OBJ \ + MXSM.OBJ \ + MXSP.OBJ \ + MXSS.OBJ \ + MXTL.OBJ \ + MXVS.OBJ \ + MXWD.OBJ \ + MXWM.OBJ \ + MXWP.OBJ \ + MXWR.OBJ + +# +# ASM compiler +# +ASMC = tasm +ASMO = /m5 /p + +# +# PAS compiler +# +PASC = tpc +PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = tlib + +.asm.obj: + $(ASMC) $(ASMO) $< + +target: modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw/modex.bak b/16/xw/modex.bak new file mode 100755 index 00000000..560a1c68 Binary files /dev/null and b/16/xw/modex.bak differ diff --git a/16/xw/modex.def b/16/xw/modex.def new file mode 100755 index 00000000..7977a4a0 --- /dev/null +++ b/16/xw/modex.def @@ -0,0 +1,163 @@ +;------------------------------------------------------------ +; +; MODEX.DEF - Include file +; Copyright (c) 1993-1994 by Alessandro Scotti +; +;JUMPS +;LOCALS + +TRUE EQU 1 ; Boolean constants +FALSE EQU 0 + +USE286 = FALSE ; TRUE enables 80286 instructions +USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions + +IF USE286 EQ TRUE + P286 +ENDIF + +IF USE386 EQ TRUE + P386 + USE286 = TRUE +ENDIF + +MXVERSION EQU 0128h ; Library version (1.40) + +;------------------------------------------------------------ +; +; VGA definitions +; +MISC EQU 3C2h ; Miscellaneous output +TS EQU 3C4h ; Timing Sequencer index register +GDC EQU 3CEh ; Graphics Data Controller index register +CRTC EQU 3D4h ; CRTC index register +STATUS EQU 3DAh ; Input Status register one + +;------------------------------------------------------------ +; +; Raster operators +; +OP_SET EQU 0 +OP_MOVE EQU 0 ; Same as OP_SET +OP_AND EQU 1 +OP_OR EQU 2 +OP_XOR EQU 3 +OP_TRANS EQU 4 +OP_ADD EQU 5 ; Must be last op + +;------------------------------------------------------------ +; +; Polygon fill functions +; +POLYSCANBUFSIZE EQU 4*1024 + +;------------------------------------------------------------ +; Macro to push registers, variables or flags onto the stack +; Usage: .push "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.PUSH has more than 10 arguments> + ENDIF + IRP $reg, + IFB <$reg> ;; Is argument blank? + EXITM ;; Yes, exit + ELSEIFIDNI <$reg>, ;; Is argument the keyword "FLAGS"? + pushf ;; Yes, push flags + ELSE + push $reg ;; Push argument + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; Macro to pop registers, variables or flags from the stack +; Usage: .pop "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.POP has more than 10 arguments> + ENDIF + IRP $reg, + IFNB <$reg> ;; Is argument non-blank? + IFIDNI <$reg>, ;; Yes, is it the keyword "FLAGS"? + popf ;; Yes, pop flags + ELSE + pop $reg ;; Pop argument + ENDIF + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; +.enter MACRO localsize + IF USE286 EQ TRUE + enter localsize, 0 + ELSE + push bp + mov bp, sp + sub sp, localsize + ENDIF +ENDM + +;------------------------------------------------------------ +; +;.leave MACRO argsize +; IF USE286 EQ TRUE +; leave +; ELSE +; mov sp, bp +; pop bp +; ENDIF +; IFNB +; ret argsize +; ELSE +; ret +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shr MACRO arg, count +; IF USE286 EQ TRUE +; shr arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shr arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shl MACRO arg, count +; IF USE286 EQ TRUE +; shl arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shl arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.chk386 MACRO name, jump +; IF USE386 EQ FALSE +; .OUT "Warning: ", , " needs a 386 or better to run!" +; jmp @@jump +; ENDIF +;ENDM diff --git a/16/xw/modex.h b/16/xw/modex.h new file mode 100755 index 00000000..2c1f1ebe --- /dev/null +++ b/16/xw/modex.h @@ -0,0 +1,153 @@ +/* + MODEX.H - C/C++ include file for the MODEX library + Copyright (c) 1994 Alessandro Scotti +*/ + +#ifndef _MODEX_H_ // Avoid nested inclusions +#define _MODEX_H_ + +// +// Video modes +// +#define MX_TEXT 0 // 80x25 text +#define MX_320x175 1 // 320x175x256 +#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5 +#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1 +#define MX_320x350 4 // 320x350x256 +#define MX_320x400 5 // 320x400x256, 2 pages +#define MX_320x480 6 // 320x480x256, 1 page +#define MX_360x175 7 // 360x175x256 +#define MX_360x200 8 // 360x200x256, 3 pages +#define MX_360x240 9 // 360x240x256, 2 pages +#define MX_360x350 10 // 360x350x256 +#define MX_360x400 11 // 360x400x256, 1 page +#define MX_360x480 12 // 360x480x256, 1 page +#define MX_400x600 13 // 400x600x256, 1 page + +// +// Fade effects +// +#define MX_FADEIN 0 +#define MX_FADEOUT 1 + +// +// Raster ops +// +#define OP_SET 0 // No operator +#define OP_AND 1 // And +#define OP_OR 2 // Or +#define OP_XOR 3 // Xor +#define OP_TRANS 4 // Transparent +#define OP_ADD 5 // Additive +#define OP_MOVE 0 // Alias for OP_SET + +// +// Temporary definitions +// +#define MXBYTE unsigned char +#define MXBOOL short int +#define MXSINT short int +#define MXUINT unsigned short int +#define MXAPI far pascal +#define MXPTR void far * + +// Functions + +#ifdef __cplusplus // Avoid C++ name mangling +extern "C" { +#endif + +// +// Initialization +// +MXSINT MXAPI mxInit( void ); // Returns 0 if successful +void MXAPI mxTerm( void ); +MXUINT MXAPI mxGetVersion( void ); +// +// Mode setting +// +void MXAPI mxChangeMode( MXUINT mode ); +void MXAPI mxSetMode( MXUINT mode ); +void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty ); +void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height ); +// +// Hardware support +// +void MXAPI mxWriteMode( MXBYTE wm ); +void MXAPI mxSplitScreen( MXUINT line ); +void MXAPI mxStartAddress( MXUINT sa ); +void MXAPI mxStartLine( MXUINT sl ); +void MXAPI mxWaitDisplay( void ); +void MXAPI mxWaitRetrace( void ); +void MXAPI mxWritePlane( MXBYTE wp ); +void MXAPI mxReadPlane( MXBYTE rp ); +void MXAPI mxRowAddress( MXBYTE ra ); +// +// Virtual screen +// +void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height ); +void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height ); +void MXAPI mxPan( MXUINT x, MXUINT y ); +// +// Clipping +// +MXBOOL MXAPI mxGetClip( void ); +MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h ); +MXBOOL MXAPI mxSetClip( MXBOOL ); +void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height ); +// +// Graphics +// +void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy ); +void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op ); +MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y ); +void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color ); +void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op ); +void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op ); +void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h ); +void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color ); +void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op ); +// +// Palette +// +void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b ); +void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue ); +void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT ); +void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step ); +// +// Text +// +MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight ); +void MXAPI mxSetTextColor( MXUINT color, MXUINT op ); +void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay ); +void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay ); +void MXAPI mxOutChar( MXSINT x, MXSINT y, char c ); +void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz ); +// +// Convex polygons +// +void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); + +#ifdef __cplusplus +} +#endif + +// +// Remove temporary defines +// +#undef MXBYTE +#undef MXBOOL +#undef MXSINT +#undef MXUINT +#undef MXPTR +#undef MXAPI + +#endif // _MODEX_H_ diff --git a/16/xw/modex.lbr b/16/xw/modex.lbr new file mode 100755 index 00000000..93fc7801 --- /dev/null +++ b/16/xw/modex.lbr @@ -0,0 +1,39 @@ ++-MXBB.OBJ & ++-MXCC.OBJ & ++-MXCG.OBJ & ++-MXCL.OBJ & ++-MXCR.OBJ & ++-MXFB.OBJ & ++-MXFP.OBJ & ++-MXGC.OBJ & ++-MXGI.OBJ & ++-MXGM.OBJ & ++-MXGP.OBJ & ++-MXGV.OBJ & ++-MXHL.OBJ & ++-MXIT.OBJ & ++-MXLL.OBJ & ++-MXLN.OBJ & ++-MXOT.OBJ & ++-MXPB.OBJ & ++-MXPF.OBJ & ++-MXPG.OBJ & ++-MXPI.OBJ & ++-MXPN.OBJ & ++-MXPP.OBJ & ++-MXPT.OBJ & ++-MXRA.OBJ & ++-MXRP.OBJ & ++-MXSA.OBJ & ++-MXSC.OBJ & ++-MXSI.OBJ & ++-MXSL.OBJ & ++-MXSM.OBJ & ++-MXSP.OBJ & ++-MXSS.OBJ & ++-MXTL.OBJ & ++-MXVS.OBJ & ++-MXWD.OBJ & ++-MXWM.OBJ & ++-MXWP.OBJ & ++-MXWR.OBJ diff --git a/16/xw/modex.pas b/16/xw/modex.pas new file mode 100755 index 00000000..7d9d26ed --- /dev/null +++ b/16/xw/modex.pas @@ -0,0 +1,194 @@ +(* + Turbo Pascal interface to the MODEX library + Copyright (c) 1993,1994 by Alessandro Scotti +*) +unit ModeX; +interface + +const + (* Video modes *) + MX_TEXT = 0; + MX_320x175 = 1; + MX_320x200 = 2; + MX_320x240 = 3; + MX_320x350 = 4; + MX_320x400 = 5; + MX_320x480 = 6; + MX_360x175 = 7; + MX_360x200 = 8; + MX_360x240 = 9; + MX_360x350 = 10; + MX_360x400 = 11; + MX_360x480 = 12; + MX_400x600 = 13; + + (* Fade effects *) + MX_FADEIN = 0; + MX_FADEOUT = 1; + + (* Raster ops *) + OP_SET = 0; + OP_AND = 1; + OP_OR = 2; + OP_XOR = 3; + OP_TRANS = 4; + OP_ADD = 5; + OP_MOVE = 0; (* Alias for OP_SET *) + +procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer ); +procedure mxCircle( CX, CY: integer; Radius: word; Color: byte ); +procedure mxChangeMode( Mode: word ); +procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word ); +procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word ); +procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word ); +procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word ); +procedure mxGetAspect( var AspectX, AspectY: word ); +function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean; +function mxGetClip: boolean; +procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word ); +procedure mxGetPalette( Palette: pointer; Start, Count: word ); +function mxGetPixel( X, Y: word ): byte; +procedure mxGetScreenSize( var Width, Height: word ); +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); +function mxGetVersion: word; +procedure mxGetVirtualScreen( var Width, Height: word ); +procedure mxInit; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); +procedure mxOutChar( X, Y: integer; C: char ); +procedure mxOutText( X, Y: integer; S: pointer ); +procedure mxPan( X, Y: word ); +procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word ); +procedure mxPutPixel( X, Y: word; C: byte ); +procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxReadPlane( Plane: byte ); +procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer ); +procedure mxRowAddress( RowAddress: byte ); +function mxSetClip( Clip: boolean ): boolean; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); +procedure mxSetColor( Index, R, G, B: word ); +procedure mxSetFont( Font: pointer; Width, Height: word ); +procedure mxSetMode( Mode: word ); +procedure mxSetPalette( Palette: pointer; Start, Count: word ); +procedure mxSetTextColor( Color, Op: word ); +procedure mxSetTextStep( DeltaX, DeltaY: integer ); +procedure mxSetVirtualScreen( Width, Height: word ); +procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word ); +procedure mxSplitScreen( Line: word ); +procedure mxStartAddress( StartAddress: word ); +procedure mxStartLine( Line: word ); +procedure mxTerm; +procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxWaitDisplay; +procedure mxWaitRetrace; +procedure mxWriteMode( Mode: byte ); +procedure mxWritePlane( Plane: byte ); + +procedure mxFillPoly( Count: word; var Map, Points; Color: word ); +procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word ); +procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word ); + +procedure mxOutStr( X, Y: integer; S: string ); + +implementation + +procedure mxBitBlt; external; +procedure mxChangeMode( Mode: word ); external; +procedure mxCircle; external; +procedure mxColorToGray; external; +procedure mxFadePalette; external; +procedure mxFillBox; external; +procedure mxGammaCorrect; external; +procedure mxGetAspect( var AspectX, AspectY: word ); external; +function mxGetClipRegion; external; +function mxGetClip: boolean; external; +procedure mxGetImage; external; +procedure mxGetPalette( Palette: pointer; Start, Count: word ); external; +function mxGetPixel( X, Y: word ): byte; external; +procedure mxGetScreenSize( var Width, Height: word ); external; +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external; +function mxGetVersion: word; external; +procedure mxGetVirtualScreen( var Width, Height: word ); external; +procedure mxInit; external; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external; +procedure mxOutChar( X, Y: integer; C: char ); external; +procedure mxOutText( X, Y: integer; S: pointer ); external; +procedure mxPan( X, Y: word ); external; +procedure mxPutImage; external; +procedure mxPutPixel( X, Y: word; C: byte ); external; +procedure mxPutTile; external; +procedure mxReadPlane( Plane: byte ); external; +procedure mxRotatePalette; external; +procedure mxRowAddress( RowAddress: byte ); external; +function mxSetClip( Clip: boolean ): boolean; external; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external; +procedure mxSetColor( Index, R, G, B: word ); external; +procedure mxSetFont( Font: pointer; Width, Height: word ); external; +procedure mxSetMode( Mode: word ); external; +procedure mxSetPalette( Palette: pointer; Start, Count: word ); external; +procedure mxSetTextColor( Color, Op: word ); external; +procedure mxSetTextStep( DeltaX, DeltaY: integer ); external; +procedure mxSetVirtualScreen( Width, Height: word ); external; +procedure mxSplitScreen( Line: word ); external; +procedure mxStartAddress( StartAddress: word ); external; +procedure mxStartLine; external; +procedure mxStretchImage; external; +procedure mxTerm; external; +procedure mxTransPutTile; external; +procedure mxWaitDisplay; external; +procedure mxWaitRetrace; external; +procedure mxWriteMode( Mode: byte ); external; +procedure mxWritePlane( Plane: byte ); external; + +procedure mxFillPoly; external; +procedure mxGouraudPoly; external; +procedure mxTexturePoly; external; +{$L MXPB} +{$L MXPF} +{$L MXPG} +{$L MXPT} + +{$L MXBB} +{$L MXCC} +{$L MXCG} +{$L MXCL} +{$L MXCR} +{$L MXFB} +{$L MXFP} +{$L MXGI} +{$L MXGM} +{$L MXGP} +{$L MXGV} +{$L MXHL} +{$L MXIT} +{$L MXLN} +{$L MXOT} +{$L MXPI} +{$L MXPN} +{$L MXPP} +{$L MXRA} +{$L MXRP} +{$L MXSA} +{$L MXSC} +{$L MXSI} +{$L MXSL} +{$L MXSM} +{$L MXSP} +{$L MXSS} +{$L MXTL} +{$L MXVS} +{$L MXWD} +{$L MXWM} +{$L MXWP} +{$L MXWR} + +(* + Prints a Turbo Pascal string. + Note: BP 7.0 supports ASCIIZ strings (PChar type). +*) +procedure mxOutStr; +begin + S := S + #0; + mxOutText( X, Y, @S[1] ); +end; + +end. diff --git a/16/xw/modex/DEMO01.EXE b/16/xw/modex/DEMO01.EXE new file mode 100755 index 00000000..28caff88 Binary files /dev/null and b/16/xw/modex/DEMO01.EXE differ diff --git a/16/xw/modex/DEMO01.PAS b/16/xw/modex/DEMO01.PAS new file mode 100755 index 00000000..c684acdd --- /dev/null +++ b/16/xw/modex/DEMO01.PAS @@ -0,0 +1,126 @@ +(* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + MAX_SPRITE = 100; +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO02.EXE b/16/xw/modex/DEMO02.EXE new file mode 100755 index 00000000..14e7dc72 Binary files /dev/null and b/16/xw/modex/DEMO02.EXE differ diff --git a/16/xw/modex/DEMO02.PAS b/16/xw/modex/DEMO02.PAS new file mode 100755 index 00000000..6b4fb6f9 --- /dev/null +++ b/16/xw/modex/DEMO02.PAS @@ -0,0 +1,125 @@ +(* + DEMO02 - Texture mapping and palette rotation + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Plasma, Threed; + +const + LSIZE = 85; + Trans : TPoint = ( X:0; Y:0; Z:0 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of T2DPoint; + Width : word; + Data : array[ 1..64*64 ] of byte; + end; + TQuad = record + VtxCnt : word; + Vtx : array[ 0..3 ] of word; + Texture: word; + end; +var + Vtx : array[ 0..7 ] of TPoint; + XVtx : array[ 0..7 ] of TPoint; + VVtx : array[ 0..7 ] of T2DPoint; + Face : array[ 0..5 ] of TQuad; + Txts : array[ 0..5 ] of TTexture; + Nrm : array[ 0..5 ] of TPoint; + XNrm : array[ 0..5 ] of TPoint; + Page : word; + Palette: array[ byte ] of record R, G, B: byte; end; + +(* Make a 64x64 plasma to be used as texture *) +procedure MakeTexture( Idx: word ); +var + I: word; +begin + mxFillBox( 0, 0, 64, 64, 0, OP_SET ); + MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 ); + mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 ); + (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *) + with Txts[Idx] do begin + Desc[0].X := $80; Desc[0].Y := $80; + Desc[1].X := $80; Desc[1].Y := $3F80; + Desc[2].X := $3F80; Desc[2].Y := $3F80; + Desc[3].X := $3F80; Desc[3].Y := $80; + Width := 64; + end; +end; + +procedure Init; +var + I: integer; +begin + (* Build vertexes for a cube *) + with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + for I:=0 to 7 do begin (* Make points 16:16 fixed *) + Vtx[I].X := Vtx[I].X*$10000; + Vtx[I].Y := Vtx[I].Y*$10000; + Vtx[I].Z := Vtx[I].Z*$10000; + end; + (* Build faces *) + with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end; + with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end; + with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end; + with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end; + with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end; + with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end; + for I:=0 to 5 do Face[I].Texture := I; + (* Build textures and palette *) + Randomize; + FillChar( Palette, SizeOf(Palette), 0 ); + MakePlasmaPalette( Palette, PAL_RGB ); + mxSetPalette( @Palette, 0, 193 ); + for I:=0 to 5 do MakeTexture( I ); +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, 8 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + mxRotatePalette( @Palette[1], 192, 3 ); (* Rotate palette *) + (* Draw cube: backface culling is straighforward in this case, so *) + (* it can be handled by the polygon filling procedure *) + for I:=0 to 5 do + mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width ); + mxStartLine( Page ); (* Flip pages *) + mxSetPalette( @Palette[1], 1, 192 ); (* Set new palette *) + Page := 240-Page; + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO03.EXE b/16/xw/modex/DEMO03.EXE new file mode 100755 index 00000000..c646c4b0 Binary files /dev/null and b/16/xw/modex/DEMO03.EXE differ diff --git a/16/xw/modex/DEMO03.PAS b/16/xw/modex/DEMO03.PAS new file mode 100755 index 00000000..01d10f49 --- /dev/null +++ b/16/xw/modex/DEMO03.PAS @@ -0,0 +1,152 @@ +(* + DEMO03 - Simple star animation, morphs between a cube and a sphere + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 1000; (* Number of points *) + EDGE = 70; (* Length of cube edge *) + RADIUS = 90; (* Radius of sphere *) + WAITCOUNT = 192; (* Frames to wait for non-morphing shapes *) + MS = 32; (* Number of steps for morphing *) + Trans : TPoint = ( X:0; Y:0; Z:0 ); + InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 ); + InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS ); + InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 ); + InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 ); +type + T2DPoint = record + X, Y: integer; + end; + T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint; + P3DPointArray = ^T3DPointArray; +var + CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray; + VVtx : array[ 0..MAXVTX-1 ] of T2DPoint; + Page : word; + Status, Count, Delta1, Delta2, Morph1, Morph2: integer; + +procedure Swap( var A, B: longint ); +var + L: longint; +begin + L := A; A := B; B := L; +end; + +function Toggle( A: longint ): longint; +begin + Toggle := A; + if( Random(2) = 0 ) then Toggle := -A; +end; + +procedure Init; +label Retry; +var + I: integer; +begin + New( CubeVtx ); + New( SphereVtx ); + New( Vtx ); + New( XVtx ); + (* Build vertexes (yes, I know this piece of code is terrible) *) + Randomize; + for I:=0 to MAXVTX-1 do begin + with CubeVtx^[I] do begin + (* Build cube *) + X := (longint(Random(2*EDGE))-EDGE)*$10000; + Y := (longint(Random(2*EDGE))-EDGE)*$10000; + Z := Toggle( EDGE*$10000 ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + end; + with SphereVtx^[I] do begin + (* Build sphere *) +Retry: + X := (longint(Random(2*RADIUS))-RADIUS); + Y := (longint(Random(2*RADIUS))-RADIUS); + if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry; + Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + X := X * $10000; Y := Y * $10000; Z := Z * $10000; + end; + end; + (* Initialize morphing *) + Move( CubeVtx^, Vtx^, SizeOf(Vtx^) ); + Status := 0; + Count := WAITCOUNT; +end; + +procedure Morph; +var + I: integer; +begin + (* Fully unoptimized, slowest loop I could think of! *) + for I:=0 to MAXVTX-1 do begin + Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS; + Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS; + Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS; + end; +end; + +var + AX, AY, AZ: byte; + I: word; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + C := #0; + repeat + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx^, XVtx^, MAXVTX ); (* 3D transform points *) + tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw points *) + for I:=0 to MAXVTX-1 do + mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 ); + mxStartLine( Page ); (* Flip pages *) + Page := 240-Page; + (* Morph *) + if( Odd(Status) ) then begin + Morph; + Inc( Morph1, Delta1 ); + Inc( Morph2, Delta2 ); + if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status ); + if( Status = 4 ) then Status := 0; + end + else begin + Dec( Count ); + if( Count < 0 ) then begin + Inc( Status ); + Count := WAITCOUNT; + Morph1 := InitMorph1[Status]; + Morph2 := InitMorph2[Status]; + Delta1 := InitDelta1[Status]; + Delta2 := InitDelta2[Status]; + end; + end; + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO04.DAT b/16/xw/modex/DEMO04.DAT new file mode 100755 index 00000000..72aaad08 Binary files /dev/null and b/16/xw/modex/DEMO04.DAT differ diff --git a/16/xw/modex/DEMO04.EXE b/16/xw/modex/DEMO04.EXE new file mode 100755 index 00000000..1fec5e8a Binary files /dev/null and b/16/xw/modex/DEMO04.EXE differ diff --git a/16/xw/modex/DEMO04.PAS b/16/xw/modex/DEMO04.PAS new file mode 100755 index 00000000..1a946315 --- /dev/null +++ b/16/xw/modex/DEMO04.PAS @@ -0,0 +1,198 @@ +(* + DEMO04 - Multiple textures and triple buffering (3 pages) + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 256; + MAXCUB = 2; + MAXTXT = 2; + Trans : TPoint = ( X:0; Y:0; Z:0 ); + TxtSunDial: array[ 0..7 ] of word = ( + $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 ); + TxtSapphire : array[ 0..7 ] of word = ( + $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 ); + TxtMarble: array[ 0..7 ] of word = ( + $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of record X, Y: word end; + Width : word; + Data : pointer; + end; + TQuad = record + Vtx : array[ 0..3 ] of word; + Texture: word; + end; + TCube = record + Face : array[ 0..5 ] of TQuad; + Base : integer; + end; +var + Vtx, XVtx: array[ 0..MAXVTX ] of TPoint; + VVtx : array[ 0..MAXVTX ] of T2DPoint; + Cube : array[ 0..MAXCUB ] of TCube; + ZList : array[ 0..MAXCUB ] of integer; + VtxCnt : word; + Txts : array[ 0..MAXTXT ] of TTexture; + Page : word; + Palette : array[ byte ] of record R, G, B: byte; end; + TxtDat1, TxtDat2: pointer; + +(* Add a new entry to the vertex array *) +procedure AddVtx( PX, PY, PZ: longint ); +begin + with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end; + Inc( VtxCnt ); +end; + +procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer ); +const + FaceIdx: array[ 0..23 ] of integer = ( + 0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 ); +var + I, VC: integer; +begin + VC := VtxCnt; + C.Base := VC; + AddVtx( X1+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y2+TY, Z2+TZ ); + AddVtx( X1+TX, Y2+TY, Z2+TZ ); + for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I]; + for I:=0 to 5 do C.Face[I].Texture := Texture; +end; + +procedure MakeTexture( Idx: integer; var VtxData ); +var + P: ^word; + I: integer; +begin + P := @VtxData; + with Txts[Idx] do begin + for I:=0 to 3 do begin + Desc[I].X := P^; Inc( P ); + Desc[I].Y := P^; Inc( P ); + end; + Width := 129; + Data := TxtDat1; + end; +end; + +procedure Init; +var + I: integer; + V: integer; + F: file; + P: array[ 1..768 ] of byte; +begin + (* Initialize objects *) + VtxCnt := 0; + MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 ); (* Sundial *) + Cube[0].Face[0].Texture := 0; + V := VtxCnt; + MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *) + tdSetTranslation( Trans ); + tdSetRotation( 32, 32, 00 ); + tdRotate( Vtx[V], XVtx[V], 8 ); (* Got to rotate this cube *) + for I:=V to V+7 do begin + Vtx[I].X := XVtx[I].X; + Vtx[I].Y := XVtx[I].Y; + Vtx[I].Z := XVtx[I].Z + 100*$10000; + end; + MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *) + (* Load texture and palette *) + Assign( F, 'DEMO04.DAT' ); + Reset( F, 1 ); + BlockRead( F, P, SizeOf(P) ); + mxSetPalette( @P, 0, 256 ); + GetMem( TxtDat1, 63*1024 ); + BlockRead( F, TxtDat1^, 129*286 ); + Close( F ); + TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 ); + (* Init textures *) + MakeTexture( 0, TxtSundial ); + MakeTexture( 1, TxtMarble ); + MakeTexture( 2, TxtSapphire ); + Txts[2].Data := TxtDat2; +end; + +(* Sort procedure, not worth optimizing with only a few objects *) +procedure SortObjects; +var + I, J, K: integer; + ZMax: array[ 0..MAXCUB ] of longint; + ZI: integer; + L: longint; +begin + for I:=0 to MAXCUB do begin + L := XVtx[Cube[I].Base].Z; + for J:=1 to 7 do + if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z; + ZMax[I] := L; + ZList[I] := I; + end; + for I:=0 to MAXCUB-1 do begin + ZI := I; + for J:=I+1 to MAXCUB do + if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J; + if( ZI <> I ) then begin + K := ZList[I]; + ZList[I] := ZList[ZI]; + ZList[ZI] := K; + end; + end; +end; + +var + AX, AY, AZ: byte; + I, J, K: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + (* Init 3D transforms, perspective is intentionally exaggerated *) + AX := 0; AY := 0; AZ := 0; + tdSetTranslation( Trans ); + tdSetPerspective( 600*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, VtxCnt ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 1 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw objects *) + SortObjects; + for I:=0 to MAXCUB do with Cube[ZList[I]] do begin + for J:=0 to 5 do begin + K := Face[J].Texture; + mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width ); + end; + end; + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* If the frame rate seems low, try to remove this line *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO05.EXE b/16/xw/modex/DEMO05.EXE new file mode 100755 index 00000000..21a7c207 Binary files /dev/null and b/16/xw/modex/DEMO05.EXE differ diff --git a/16/xw/modex/DEMO05.PAS b/16/xw/modex/DEMO05.PAS new file mode 100755 index 00000000..819c5cf3 --- /dev/null +++ b/16/xw/modex/DEMO05.PAS @@ -0,0 +1,131 @@ +(* + DEMO05 - A Gouraud-shaded rotating torus + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex, Threed; + +(* Define ALTPAL for alternate palette *) +{$define ALTPAL} + +const + MAXVTX1 = 15; RADIUS1 = 70; (* MAXVTX1+1 must be multiple of 4 *) + MAXVTX2 = 15; RADIUS2 = 30; + MAXVTX = (MAXVTX1+1)*(MAXVTX2+1)-1; + MAXFACE = MAXVTX; + Trans : TPoint = ( X:0; Y:0; Z:0 ); (* Object translation *) + Light : TPoint = ( X:0; Y:0; Z:-63*$10000 ); (* Light direction *) +type + TQuad = record + QVtx : array[ 0..3 ] of integer; + end; +var + Vtx, XVtx : array[ 0..MAXVTX ] of TPoint; (* Points *) + VVtx : array[ 0..MAXVTX ] of record X, Y: integer end; + Face : array[ 0..MAXFACE ] of TQuad; (* Polys *) + Culled : array[ 0..MAXFACE ] of integer; + GNrm,XGNrm: array[ 0..MAXVTX ] of TVector; (* Gouraud normals *) + VtxLight : array[ 0..MAXVTX ] of integer; (* Points brightness *) + Page : word; + +function GetVtx( I1, I2: integer ): integer; +begin + GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1); +end; + +procedure Init; +var + R, N, X, Y, Z: real; + I, J, K, V: integer; +begin + (* Build vertexes *) + for I:=0 to MAXVTX1 do begin + K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1); + R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) ); + for J:=0 to MAXVTX2 do begin + V := I*(MAXVTX2+1)+J; (* Index of current vertex *) + (* Compute coordinates of current vertex *) + X := R*Cos(2*J*Pi / (MAXVTX2+1)); (* Get coordinates *) + Y := R*Sin(2*J*Pi / (MAXVTX2+1)); + Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1)); + Vtx[V].X := Round( X )*$10000; (* Save coordinates *) + Vtx[V].Y := Round( Y )*$10000; + Vtx[V].Z := Round( Z )*$10000; + (* Compute direction of Gouraud normal thru current vertex *) + X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1)); + Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1)); + N := Sqrt( X*X + Y*Y + Z*Z ); (* Get vector length *) + GNrm[V].X := Trunc( X*$10000/N ); (* Save normal vector *) + GNrm[V].Y := Trunc( Y*$10000/N ); + GNrm[V].Z := Trunc( Z*$10000/N ); + end; + end; + (* Generate faces so that depth-sorting is not needed: there are still *) + (* some *very* little errors, but this is the best I could devise *) + J := 0; + K := 0; + for I:=0 to MAXFACE do with Face[I] do begin + QVtx[0] := GetVtx( J, K ); + QVtx[1] := GetVtx( J, K+1 ); + QVtx[2] := GetVtx( J+1, K+1 ); + QVtx[3] := GetVtx( J+1, K ); + Inc( K ); + if( K > MAXVTX2 ) then begin + K := 0; + Inc( J ); + end; + end; +{$ifndef ALTPAL} + for I:=0 to 63 do mxSetColor( I+64, 0, 0, I ); (* Blue palette *) +{$else} + for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *) + for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 ); +{$endif} +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetLight( Light ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, MAXVTX+1 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page ); + tdRotate( GNrm, XGNrm, MAXVTX+1 ); (* Rotate Gouraud normals *) + tdTransformLight( XGNrm, VtxLight, MAXVTX+1 ); + (* Backplane culling is not really needed here! *) + FillChar( Culled, SizeOf(Culled), 0 ); + tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 3 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw polygons *) + for I:=0 to MAXFACE do with Face[I] do + if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 ); + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* Uncomment this instruction if screen flickers *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO06.DAT b/16/xw/modex/DEMO06.DAT new file mode 100755 index 00000000..1ac2c2bb Binary files /dev/null and b/16/xw/modex/DEMO06.DAT differ diff --git a/16/xw/modex/DEMO06.EXE b/16/xw/modex/DEMO06.EXE new file mode 100755 index 00000000..f1308e8a Binary files /dev/null and b/16/xw/modex/DEMO06.EXE differ diff --git a/16/xw/modex/DEMO06.PAS b/16/xw/modex/DEMO06.PAS new file mode 100755 index 00000000..f26af067 --- /dev/null +++ b/16/xw/modex/DEMO06.PAS @@ -0,0 +1,135 @@ +(* + DEMO06 - Magnifying glass + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + R = 40; (* Lens radius *) + K : real = 1.8; (* Magnifying factor, less makes a stronger lens *) +type + TLine = array[ 0..319 ] of byte; + PLine = ^TLine; + TScreen = array[ 0..239 ] of PLine; +var + VScreen: TScreen; (* Virtual screen *) + BallX : array[ 0..R, 0..R ] of integer; + BallY : array[ 0..R, 0..R ] of integer; + Sprite : array[ -R..R, -R..R ] of byte; + Page : word; + +(* Returns "lens-view" coordinates of X,Y *) +procedure GetCoords( var X, Y: integer ); +var + LR, Z, SinA, SinB, TgB, Q: real; +begin + LR := Sqrt( X*X + Y*Y ); + if( LR = 0 ) then Exit; + if( LR < R ) then begin + Z := Sqrt( R*R - LR*LR ); + SinA := LR / R; + SinB := SinA / K; + TgB := SinB / Sqrt( 1-SinB*SinB ); + Q := LR - TgB*Z; + X := Round( X * ( Q/LR ) ); + Y := Round( Y * ( Q/LR ) ); + end; +end; + +procedure Init; +var + F : file; + Palette: array[ 0..767 ] of record R, G, B: byte; end; + X, Y, + X2, Y2 : integer; +begin + (* Load background image *) + Assign( F, 'demo06.dat' ); + Reset( F, 1 ); + BlockRead( F, Palette, 768 ); + mxSetPalette( @Palette, 0, 256 ); + for Y:=0 to 239 do begin + New( VScreen[Y] ); + BlockRead( F, VScreen[Y]^, 320 ); + mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE ); + end; + Close( F ); + (* Build lens *) + for X:=0 to R do begin + for Y:=0 to R do begin + X2 := X; + Y2 := Y; + GetCoords( X2, Y2 ); + BallX[X, Y] := X2; + BallY[X, Y] := Y2; + end; + end; +end; + +procedure PutLens( OX, OY: integer ); +var + X, Y: integer; +begin + for X:=0 to R do begin + for Y:=0 to R do begin + Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + end; + end; + (* Draw the sprite *) + mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE ); +end; + +function Delta: integer; +begin + Delta := Random(3)+2; +end; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*Delta; + end; +end; + +var + X, Y, DX, DY: integer; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; + X := R; + Y := R; + Randomize; + DX := Delta; + DY := Delta; + + (* Main loop *) + repeat + (* Update video *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + PutLens( X, Y ); + mxCircle( X, Page+Y, R, 0 ); + (* Update lens coordinates *) + Inc( X, DX ); + Check( X+R >= 319, X, DX, 319-R, -1 ); + Check( X <= R, X, DX, R, +1 ); + Inc( Y, DY ); + Check( Y+R >= 239, Y, DY, 239-R, -1 ); + Check( Y <= R, Y, DY, R, +1 ); + (* Flip pages: double buffering, avoid wait for display *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 0; end; + end; + mxWaitRetrace; (* Wait for hidden page to show *) + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/DEMO07.EXE b/16/xw/modex/DEMO07.EXE new file mode 100755 index 00000000..8a401169 Binary files /dev/null and b/16/xw/modex/DEMO07.EXE differ diff --git a/16/xw/modex/DEMO07.PAS b/16/xw/modex/DEMO07.PAS new file mode 100755 index 00000000..04fff790 --- /dev/null +++ b/16/xw/modex/DEMO07.PAS @@ -0,0 +1,68 @@ +(* + DEMO07 - Hardware scrolling + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + (* Change this if scrolling seems jerky (this simple program does *) + (* not handle vertical retrace/display very well) *) + STEPS = 5; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*(Random(3)+2); + end; +end; + +var + I, X, Y, DX, DY: integer; +begin + (* Initialize library and graphics mode *) + mxInit; + mxSetMode( MX_320x200 ); + (* Set a 640x400 virtual screen *) + mxSetVirtualScreen( 640, 400 ); + mxSetClip( TRUE ); + + X := 0; + Y := 0; + DX := 1; + DY := 1; + + (* Main loop: draw lines, circles, points and rectangles in separate *) + (* 320x200 windows, while smoothly panning virtual screen *) + while( not KeyPressed ) do begin + (* Points *) + mxSetClipRegion( 0, 0, 320, 200 ); + for I:=1 to STEPS do + mxPutPixel( Random(320), Random(200), Random(16) ); + (* Lines *) + mxSetClipRegion( 0, 200, 320, 200 ); + for I:=1 to STEPS do + mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET ); + (* Circles *) + mxSetClipRegion( 320, 0, 320, 200 ); + for I:=1 to STEPS do + mxCircle( Random(320)+320, Random(200), Random(100), Random(16) ); + (* Boxes *) + mxSetClipRegion( 320, 200, 320, 200 ); + for I:=1 to STEPS do + mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET ); + (* Pan *) + Inc( X, DX ); + Check( X+320 >= 639, X, DX, 319, -1 ); + Check( X < 0, X, DX, 0, +1 ); + Inc( Y, DY ); + Check( Y+200 >= 399, Y, DY, 199, -1 ); + Check( Y < 0, Y, DY, 0, +1 ); + mxPan( X, Y ); + mxWaitRetrace; + end; + + (* Shutdown *) + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/MATH.INC b/16/xw/modex/MATH.INC new file mode 100755 index 00000000..742af410 --- /dev/null +++ b/16/xw/modex/MATH.INC @@ -0,0 +1,34 @@ +; +; MATH.INC - Include file for THREED.ASM +; + +; 3-dimensional point, coordinates in fixed format (16:16) +; +TPOINT STRUC + X DD ? + Y DD ? + Z DD ? +TPOINT ENDS + +; 2-dimensional point, coordinates in integer format +; +TIMAGEPOINT STRUC + IX DW ? + IY DW ? +TIMAGEPOINT ENDS + +; Fixed-point divide: EAX = EAX / arg +; +.xdiv MACRO arg + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv arg +ENDM + +; Fixed-point multiply: EAX = EAX * arg +; +.xmul MACRO arg + imul arg + shrd eax, edx, 16 +ENDM diff --git a/16/xw/modex/PLASMA.PAS b/16/xw/modex/PLASMA.PAS new file mode 100755 index 00000000..237e292a --- /dev/null +++ b/16/xw/modex/PLASMA.PAS @@ -0,0 +1,103 @@ +unit Plasma; +interface + +const + PAL_RGB = 0; + PAL_CLOUDS = 1; + PAL_LANDSCAPE = 2; + +procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte ); +procedure MakePlasmaPalette( var Palette; What: word ); + +implementation uses Modex; + +procedure NewColor( XA, YA, X, Y, XB, YB: integer ); +var + Color: longint; +begin + Color := Abs( XA-XB )+Abs( YA-YB ); + Color := Random( Color shl 1 )-Color; + Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1; + if( Color < 1 ) then Color := 1; + if( Color > 192 ) then Color := 192; + if( mxGetPixel( X, Y ) = 0 ) then + mxPutPixel( X, Y, Lo(Color) ); +end; + +procedure Divide( X1, Y1, X2, Y2: integer ); +var + X, Y, Color: integer; +begin + if not( (X2-X1<2)and(Y2-Y1<2) ) then begin + X := (X1+X2) shr 1; + Y := (Y1+Y2) shr 1; + NewColor( X1, Y1, X, Y1, X2, Y1 ); + NewColor( X2, Y1, X2, Y, X2, Y2 ); + NewColor( X1, Y2, X, Y2, X2, Y2 ); + NewColor( X1, Y1, X1, Y, X1, Y2 ); + Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+ + mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2; + mxPutPixel( X, Y, Color ); + Divide( X1, Y1, X, Y ); + Divide( X, Y1, X2, Y ); + Divide( X, Y, X2, Y2 ); + Divide( X1, Y, X, Y2 ); + end; +end; + +procedure MakePlasma; +begin + Dec( W ); + Dec( H ); + mxPutPixel( X, Y, C1 ); + mxPutPixel( X, Y+H, C2 ); + mxPutPixel( X+W, Y+H, C3 ); + mxPutPixel( X+W, Y, C4 ); + Divide( X, Y, X+W, Y+H ); +end; + +procedure MakePlasmaPalette; +type + TPal = array[ byte ] of record R, G, B: byte end; +var + I: word; +begin + FillChar( TPal(Palette)[1], 192*3, 0 ); + case What of + PAL_CLOUDS: + for I:=1 to 192 do begin + TPal(Palette)[I].R := Abs( I-96 )*63 div 96; + TPal(Palette)[I].G := Abs( I-96 )*63 div 96; + TPal(Palette)[I].B := 63; + end; + PAL_LANDSCAPE: + begin + for I:=0 to 31 do begin + TPal(Palette)[I+1].R := I; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := I + I shr 1+15; + end; + for I:=32 to 63 do begin + TPal(Palette)[I+1].R := 0; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := 0; + end; + for I:=64 to 191 do begin + TPal(Palette)[I+1].R := (I-64) div 3 + 15; + TPal(Palette)[I+1].G := (I-64) div 3 + 15; + TPal(Palette)[I+1].B := (I-64) div 3 + 15; + end; + end; + else + for I:=1 to 64 do begin + TPal(Palette)[I].G := I-1; + TPal(Palette)[I].B := 64-I; + TPal(Palette)[I+64].R := I-1; + TPal(Palette)[I+64].G := 64-I; + TPal(Palette)[I+128].B := I-1; + TPal(Palette)[I+128].R := 64-I; + end; + end; +end; + +end. \ No newline at end of file diff --git a/16/xw/modex/QIX2.EXE b/16/xw/modex/QIX2.EXE new file mode 100755 index 00000000..a10d7db5 Binary files /dev/null and b/16/xw/modex/QIX2.EXE differ diff --git a/16/xw/modex/QIX2.PAS b/16/xw/modex/QIX2.PAS new file mode 100755 index 00000000..d1b59791 --- /dev/null +++ b/16/xw/modex/QIX2.PAS @@ -0,0 +1,210 @@ +{$E-,N+} +uses Crt, Modex; + +const + DEFVERT = 12; (* Vertex count *) + DEFREPL = 3; (* Repetition count *) + DEFQIXS = 2; (* Qixs *) + FADESPEED = 48; +type + TPoint = record + X, Y : integer; + end; + TRGB = record + R, G, B: byte; + end; + TQix = record + Color: integer; + Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint; + Delta: array[ 0..DEFVERT-1 ] of TPoint; + end; +var + Page : integer; + MaxX, + MaxY : word; + Qix : array[ 0..DEFQIXS-1 ] of TQix; + Pal : array[ byte ] of TRGB; + +type + TReal = double; + TRPoint = record + X, Y: TReal; + end; + TMatrix = array[ 0..3, 0..3 ] of TReal; +var + M: TMatrix; + G: array[ 0..DEFVERT-1 ] of TRPoint; + C: array[ 0..DEFVERT-1 ] of TRPoint; + +procedure BumpPal( Idx, DR, DG, DB, Steps: integer ); +var + I: integer; +begin + for I:=1 to Steps do begin + Pal[Idx+1].R := Pal[Idx].R + DR; + Pal[Idx+1].G := Pal[Idx].G + DG; + Pal[Idx+1].B := Pal[Idx].B + DB; + Inc( Idx ); + end; +end; + +procedure InitPalette; +begin + with Pal[0] do begin R:=0; G:=0; B:=0; end; + with Pal[1] do begin R:=0; G:=0; B:=62; end; + BumpPal( 1, 0, 2, -2, 31 ); + BumpPal( 32, 2, -2, 0, 31 ); + BumpPal( 63, -2, 2, 2, 31 ); + BumpPal( 94, 2, 0, -2, 31 ); + BumpPal( 125, -2, -2, 2, 31 ); +end; + +procedure Init( var Qix: TQix; Color: integer ); +var + I: integer; +begin + FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 ); + for I:=0 to DEFVERT-1 do begin + Qix.Vert[I, DEFREPL-1].X := Random( MaxX ); + Qix.Vert[I, DEFREPL-1].Y := Random( MaxY ); + Qix.Delta[I].X := Random(5)+1; + Qix.Delta[I].Y := Random(5)+1; + end; + Qix.Color := Color; + + (* Initialize matrix (Catmull-Rom) *) + M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2; + M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2; + M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0; + M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0; +end; + +procedure mxBezier( var Qix: TQix; I0, Idx, N: integer ); +var + I, J: integer; + T, T2, T3: TReal; + X0, Y0, X, Y: TReal; + Delta: TReal; +begin + (* Compute coefficients *) + for I:=0 to 3 do begin + C[I].X := 0; + for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X; + C[I].Y := 0; + for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y; + end; + X0 := C[3].X; + Y0 := C[3].Y; + Delta := 1 / N; + T := 0; + for I:=1 to N do begin + T := T + Delta; + T2 := T*T; + T3 := T*T2; + X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X; + Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y; + mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET ); + X0 := X; + Y0 := Y; + end; +end; + +procedure Plot( var Qix: TQix; Idx: integer ); +var + I, J: integer; +begin + for I:=0 to DEFVERT-1 do begin + mxBezier( Qix, I, Idx, 12 ); + end; +end; + +procedure Update( var Qix: TQix; Idx: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Inc( Vert[I,Idx].X, Delta[I].X ); + if( Vert[I,Idx].X < 0 ) then begin + Vert[I,Idx].X := 0; + Delta[I].X := Random( 5 )+1; + end; + if( Vert[I,Idx].X > MaxX ) then begin + Vert[I,Idx].X := MaxX; + Delta[I].X := -Random( 5 )-1; + end; + Inc( Vert[I,Idx].Y, Delta[I].Y ); + if( Vert[I,Idx].Y < 0 ) then begin + Vert[I,Idx].Y := 0; + Delta[I].Y := Random( 5 )+1; + end; + if( Vert[I,Idx].Y > MaxY ) then begin + Vert[I,Idx].Y := MaxY; + Delta[I].Y := -Random( 5 )-1; + end; + end; +end; + +procedure Copy( var Qix: TQix; Dest, Src: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Vert[I,Dest].X := Vert[I,Src].X; + Vert[I,Dest].Y := Vert[I,Src].Y; + end; +end; + +procedure AnimateQix; +var + Q, Idx, I, J, P, Count: integer; +begin + Count := 0; + P := DEFREPL-1; + I := 0; + J := 1; + repeat + mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 ); + mxSetClip( TRUE ); + mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET ); + for Q:=0 to DEFQIXS-1 do begin + Copy( Qix[Q], I, P ); + Update( Qix[Q], I ); + for Idx:=0 to DEFREPL-1 do begin + Plot( Qix[Q], Idx ); + end; + end; + I := (I+1) mod DEFREPL; + J := (J+1) mod DEFREPL; + P := (P+1) mod DEFREPL; + Inc( Count ); + mxStartLine( Page ); + if( Count >= FADESPEED ) then begin + for Q:=0 to DEFQIXS-1 do begin + Inc( Qix[Q].Color ); + if( Qix[Q].Color > 156 ) then + Qix[Q].Color := 1; + end; + Count := 0; + end; + Page := 240-Page; + until( KeyPressed ); +end; + +var + I: integer; +begin + Randomize; + mxInit; + mxSetMode( MX_320x240 ); + mxGetScreenSize( MaxX, MaxY ); + for I:=0 to DEFQIXS-1 do + Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 ); + InitPalette; + mxSetPalette( @Pal, 0, 157 ); + Page := 240; + Dec( MaxX ); + Dec( MaxY ); + AnimateQix; + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw/modex/README.TXT b/16/xw/modex/README.TXT new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw/modex/README.TXT @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw/modex/SINCOS.INC b/16/xw/modex/SINCOS.INC new file mode 100755 index 00000000..6986eeeb --- /dev/null +++ b/16/xw/modex/SINCOS.INC @@ -0,0 +1,518 @@ +; +; SINCOS.INC - Sin/cos tables for THREED.ASM +; + +tblSin LABEL DWORD + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 +tblCos LABEL DWORD + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 diff --git a/16/xw/modex/THREED.ASM b/16/xw/modex/THREED.ASM new file mode 100755 index 00000000..5ecd3ba3 --- /dev/null +++ b/16/xw/modex/THREED.ASM @@ -0,0 +1,872 @@ +COMMENT / + Fixed-point math functions and 3D transforms + Copyright (c) 1993,94 by Alessandro Scotti +/ +WARN PRO +P386 +JUMPS +LOCALS + +INCLUDE MATH.INC + +PUBLIC tdFixedMul +PUBLIC tdGetNormal +PUBLIC tdRotate +PUBLIC tdGetSurfaceLight +PUBLIC tdSetLight +PUBLIC tdSetRotation +PUBLIC tdSetTranslation +PUBLIC tdTransform +PUBLIC tdTransformToImage +PUBLIC tdTransformLight +PUBLIC tdBackPlaneCull +PUBLIC tdSetPerspective + +;----------------------------------------------------------- +; +; Data segment +; +MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' + ASSUME ds:MATH_DATA + +INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table + +XRotation TPOINT <> ; 3x3 rotation matrix +YRotation TPOINT <> +ZRotation TPOINT <> + +Translation TPOINT <> ; Translation vector + +Light TPOINT <> ; Light vector +AmbientLight DW 00 ; Ambient light + +XScale DD 10000h ; Scaling factor for X coordinate +YScale DD 10000h ; Scaling factor for Y coordinate +PerspectiveDistance DD 20000000h + +MATH_DATA ENDS + +;----------------------------------------------------------- +; +; Code segment +; +MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING + +tdSetPerspective PROC PASCAL FAR + ARG Perspective:DWORD, \ + ScaleX:DWORD, \ + ScaleY:DWORD + USES ds + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov eax, [Perspective] + mov [PerspectiveDistance], eax + mov eax, [ScaleX] + mov [XScale], eax + mov eax, [ScaleY] + mov [YScale], eax + + ret +tdSetPerspective ENDP + + +;----------------------------------------------------------- +; +; Sets the rotation matrix. +; +; Input: +; RX = X-axis rotation angle +; RY = X-axis rotation angle +; RZ = X-axis rotation angle +; Output: +; none +; +tdSetRotation PROC PASCAL FAR + ARG RX:WORD, \ + RY:WORD, \ + RZ:WORD + USES ds, si, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov bx, [RZ] + mov si, [RY] + mov di, [RX] + shl bx, 2 + shl si, 2 + shl di, 2 + + push ebp ; We use EBP as a scratch register + +; Set X rotation + mov eax, tblCos[bx] + imul tblCos[si] + mov [XRotation.X], edx + + mov eax, tblSin[bx] + imul tblCos[si] + mov [XRotation.Y], edx + + mov eax, tblSin[si] + sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 + mov [XRotation.Z], eax + +; Set Y rotation + mov eax, tblCos[bx] + imul tblSin[si] ; EDX:EAX = fixed 16:48 + shrd eax, edx, 24 ; EAX = fixed 8:24 + imul tblSin[di] ; EDX:EAX = fixed 16:48 + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblCos[di] + add eax, ebp + adc edx, ecx ; EDX:EAX = fixed 16:48 + neg edx + mov [YRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblSin[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblCos[di] + sub eax, ebp + sbb edx, ecx + mov [YRotation.Y], edx + + mov eax, tblCos[si] + imul tblSin[di] + mov [YRotation.Z], edx + +; Set Z rotation + mov eax, tblCos[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblSin[di] + sub eax, ebp + sbb edx, ecx + mov [ZRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblSin[di] + add eax, ebp + add edx, ecx + neg edx + mov [ZRotation.Y], edx + + mov eax, tblCos[si] + imul tblCos[di] + mov [ZRotation.Z], edx + + pop ebp ; Restore EBP + + ret +tdSetRotation ENDP + +;----------------------------------------------------------- +; +; Sets the translation vector. +; +; Input: +; TV = pointer to translation vector +; Output: +; none +; +tdSetTranslation PROC PASCAL FAR + ARG TV:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [TV] + mov eax, es:[di].X + mov [Translation.X], eax + mov eax, es:[di].Y + mov [Translation.Y], eax + mov eax, es:[di].Z + mov [Translation.Z], eax + + ret +tdSetTranslation ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdTransform PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + LOCAL Adjust:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + + ALIGN DWORD +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + mov ebx, eax + shrd eax, edx, 16 + add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) + mov es:[di].Z, eax +; Get perspective factor + mov ebx, [PerspectiveDistance] + sub eax, ebx + neg eax ; EAX = PD - Z + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv ebx ; EAX = fixed 16:16 result + mov [Adjust], eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.X] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.Y] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdTransform ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT into an array of TIMAGEPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TIMAGEPOINT +; Count = number of entries to transform +; DeltaX = translation distance for the X coordinate +; DeltaY = translation distance for the Y coordinate +; Output: +; the maximum Z value +; +tdTransformToImage PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD + LOCAL Adjust:DWORD, \ + Max:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + mov [Max], 80000000h + +@@Loop: +; Check max Z + mov eax, fs:[si].Z + cmp eax, [Max] + jle @@1 + mov [Max], eax +@@1: + +; Transform X coordinate + mov ax, WORD PTR fs:[si].X[2] + add ax, [DeltaX] + mov es:[di].IX, ax + +; Transform Y coordinate + mov ax, WORD PTR fs:[si].Y[2] + add ax, [DeltaY] + mov es:[di].IY, ax + + add si, SIZE TPOINT + add di, SIZE TIMAGEPOINT + dec [Count] + jnz @@Loop + + mov eax, [Max] + shld edx, eax, 16 + ret +tdTransformToImage ENDP + +;----------------------------------------------------------- +; +; Sets the light source. +; +; Input: +; Light = pointer to light vector +; Output: +; none +; +tdSetLight PROC PASCAL FAR + ARG L:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [L] + mov eax, es:[di].X + mov [Light.X], eax + mov eax, es:[di].Y + mov [Light.Y], eax + mov eax, es:[di].Z + mov [Light.Z], eax + + ret +tdSetLight ENDP + +;----------------------------------------------------------- +; +; Computes light intensity for an array of surfaces. +; +; Input: +; Normals = pointer to an array of surface normals +; Lights = pointer to an array of integer to be filled with +; light intensity +; Count = number of elements to transform +; Output: +; none +; +tdTransformLight PROC PASCAL FAR + ARG Normals:DWORD, \ + Lights:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov fs, ax + ASSUME fs:MATH_DATA + + lds si, [Normals] + les di, [Lights] + ASSUME ds:NOTHING + +; Intensity is given by the dot product between the Light vector and +; the surface normal +@@Loop: + mov eax, ds:[si].Z + imul [Light.Z] + mov ebx, eax + mov ecx, edx + mov eax, ds:[si].Y + imul [Light.Y] + add ebx, eax + adc ecx, edx + mov eax, ds:[si].X + imul [Light.X] + add eax, ebx + adc edx, ecx ; EDX:EAX = fixed 32:32 intensity + add dx, [AmbientLight] + test dx, dx + jg @@1 + xor dx, dx ; Return 0 for no light +@@1: + mov es:[di], dx + inc di + inc di + add si, SIZE TPOINT + dec [Count] + jnz @@Loop + + ASSUME fs:NOTHING + ret +tdTransformLight ENDP + +;----------------------------------------------------------- +; +; Returns the light value given the normal to a surface. +; +; Input: +; Normal = pointer to TPOINT surface normal vector +; Output: +; AX = light intensity (>=0) +; Notes: +; the normal is rotated according to the current setting. +; +tdGetSurfaceLight PROC PASCAL FAR + ARG Normal:DWORD + USES ds, esi, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [Normal] + +; Transform Z coordinate + mov eax, es:[di].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.Z] + shrd eax, edx, 16 + mov esi, eax + +; Transform X coordinate + mov eax, es:[di].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add esi, eax + +; Transform Y coordinate + mov eax, es:[di].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add eax, esi + shr eax, 16 + +; Add ambient light + add ax, [AmbientLight] + test ax, ax + jge @@Exit + xor ax, ax + +@@Exit: + ret +tdGetSurfaceLight ENDP + +;----------------------------------------------------------- +; +; Rotates an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdRotate PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Z, eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdRotate ENDP + +tdFixedMul PROC PASCAL FAR + ARG F1:DWORD, \ + F2:DWORD + + mov eax, [F1] + imul [F2] + shr eax, 16 + + ret +tdFixedMul ENDP + +;----------------------------------------------------------- +; +; Returns in EAX the square root of EDX:EAX. +; +subSqrt PROC NEAR + push esi + push edi + + add eax, eax + adc edx, 0 + mov eax, edx ; Just discard the low bits + + mov esi, eax + xor edi, edi + shld edi, esi, 16 + shl esi, 16 +@@Loop: + mov ebx, eax + mul eax + add eax, esi + adc edx, edi + shrd eax, edx, 1 + shr edx, 1 + div ebx + cmp eax, ebx + jne @@Loop + +; Adjust EAX + shl eax, 8 + + pop edi + pop esi + ret +subSqrt ENDP + +;----------------------------------------------------------- +; +; Finds the unitary normal to a given surface. +; +; Input: +; Dest = pointer to TPOINT (vector) result +; P1, P2, P3 = pointer to TPOINT points on surface +; Output: +; none +; Notes: +; the normal is given by the cross-product between (P3-P1) and +; (P2-P1), so its orientation depends on the parameters order. +; +tdGetNormal PROC PASCAL FAR + ARG Dest:DWORD, \ + P1:DWORD, \ + P2:DWORD, \ + P3:DWORD + LOCAL V1:TPOINT, \ + V2:TPOINT, \ + N:TPOINT + USES ds, si, es, di + +; Get vector V1 + lds si, [P1] + les di, [P3] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V1.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V1.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V1.Z], eax + +; Get vector V2 + les di, [P2] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V2.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V2.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V2.Z], eax + +; Get normal vector (V1 x V2) + mov eax, [V1.Z] + imul [V2.Y] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Y] + imul [V2.Z] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.X], eax + + mov eax, [V1.X] + imul [V2.Z] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Z] + imul [V2.X] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Y], eax + + mov eax, [V1.Y] + imul [V2.X] + mov ebx, eax + mov ecx, edx + mov eax, [V1.X] + imul [V2.Y] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Z], eax + +; Get normal length + mov eax, [N.X] + imul eax + mov ebx, eax + mov ecx, edx + mov eax, [N.Y] + imul eax + add ebx, eax + adc ecx, edx + mov eax, [N.Z] + imul eax + add eax, ebx + adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z + call subSqrt ; EAX = normal length + mov ebx, eax + +; Adjust vector and save it + les di, [Dest] + mov eax, [N.X] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].X, eax + mov eax, [N.Y] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Y, eax + mov eax, [N.Z] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Z, eax + + ret +tdGetNormal ENDP + +TPOLY STRUC + Vtx DW 4 DUP(?) +TPOLY ENDS + +;----------------------------------------------------------- +; +; Performs surface removal on an array of polygons. +; +; Input: +; Poly = pointer to an array of TPOLY +; Vertex = pointer to an array of TPOINT +; Dest = pointer to an array of integer +; Count = number of polygons to check +; Step = size of TPOLY structure +; Output: +; if the n-th polygon is invisible the n-th entry of the +; Dest array is set to -1, other entries are not modified +; (so it's possible to use the Light array for Dest, because +; the light intensity is always >= 0) +; +tdBackPlaneCull PROC PASCAL FAR + ARG Step:WORD, \ + Poly:DWORD, \ + Vertex:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + ASSUME ds:NOTHING + + mov ds, WORD PTR Vertex[2] + les di, [Poly] + mov fs, WORD PTR Dest[2] + +@@Loop: + mov ax, es:[di].Vtx[2] ; Index of 2nd vertex + shl ax, 2 + mov bx, ax + shl ax, 1 + add bx, ax ; BX = index*SIZE TPOINT + add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex + mov ax, es:[di].Vtx[4] ; Index of 3rd vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex + mov ecx, ds:[si].X + sub ecx, ds:[bx].X ; ECX = V3.X-V2.X + mov edx, ds:[si].Y + sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y + mov ax, es:[di].Vtx[0] ; Index of 1st vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 1st vertex + mov eax, ds:[si].X + sub eax, ds:[bx].X ; EAX = V1.X-V2.X + mov esi, ds:[si].Y + sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y + imul edx + mov ebx, eax + xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) + mov eax, esi + imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) + sub eax, ebx + sbb edx, ecx + jl @@Next ; Polygon is visible + mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry + mov WORD PTR fs:[bx], -1 ; Remove polygon +@@Next: + add WORD PTR [Dest], 2 ; Next entry for dest + add di, [Step] ; Next polygon + dec [Count] + jnz @@Loop + + ret +tdBackPlaneCull ENDP + +MATH_TEXT ENDS +END diff --git a/16/xw/modex/THREED.H b/16/xw/modex/THREED.H new file mode 100755 index 00000000..b993ef86 --- /dev/null +++ b/16/xw/modex/THREED.H @@ -0,0 +1,32 @@ +typedef struct { + long x, y, z; +} TVECTOR; + +#define PVECTOR TVECTOR far * + +#define TPOINT TVECTOR +#define PPOINT PVECTOR + +#define VPTR void far * + +#ifdef __cplusplus +extern "C" { +#endif + +long far pascal tdFixedMul( long, long ); +int far pascal tdGetSurfaceLight( PPOINT ); +long far pascal tdTransformToImage( VPTR, VPTR, short, short, short ); + +void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short ); +void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT ); +void far pascal tdRotate( VPTR, VPTR, short ); +void far pascal tdSetLight( PVECTOR ); +void far pascal tdSetRotation( short, short, short ); +void far pascal tdSetTranslation( PVECTOR ); +void far pascal tdSetPerspective( long, long, long ); +void far pascal tdTransform( VPTR, VPTR, short ); +void far pascal tdTransformLight( VPTR, VPTR, short ); + +#ifdef __cplusplus +} +#endif diff --git a/16/xw/modex/THREED.PAS b/16/xw/modex/THREED.PAS new file mode 100755 index 00000000..8b712c9d --- /dev/null +++ b/16/xw/modex/THREED.PAS @@ -0,0 +1,40 @@ +unit ThreeD; +interface + +type + TVector = record + X, Y, Z : longint; + end; + TPoint = TVector; + +function tdFixedMul( F1, F2: longint ): longint; +function tdGetSurfaceLight( var Normal: TPoint ): integer; +function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint; + +procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word ); +procedure tdGetNormal( var Dest, P1, P2, P3: TVector ); +procedure tdRotate( var Source, Dest; Count: word ); +procedure tdSetLight( var Light: TVector ); +procedure tdSetRotation( RX, RY, RZ: word ); +procedure tdSetTranslation( var TV: TVector ); +procedure tdSetPerspective( PD, XF, YF: longint ); +procedure tdTransform( var Source, Dest; Count: word ); +procedure tdTransformLight( var Source, Dest; Count: word ); + +implementation + +function tdGetSurfaceLight; external; +procedure tdSetRotation( RX, RY, RZ: word ); external; +procedure tdGetNormal; external; +procedure tdSetTranslation( var TV: TVector ); external; +procedure tdTransform( var Source, Dest; Count: word ); external; +procedure tdRotate; external; +function tdTransformToImage; external; +procedure tdSetLight( var Light: TVector ); external; +procedure tdSetPerspective; external; +procedure tdTransformLight; external; +function tdFixedMul( F1, F2: longint ): longint; external; +procedure tdBackPlaneCull; external; +{$L THREED} + +end. diff --git a/16/xw/modex/demo01.c b/16/xw/modex/demo01.c new file mode 100755 index 00000000..0c9f3b02 --- /dev/null +++ b/16/xw/modex/demo01.c @@ -0,0 +1,140 @@ +/* + * DEMO01 - Sprites, page flipping and palette rotation + * Copyright (c) 1994 Alessandro Scotti + */ +#include ../../x/modex.h + +#DEFINE MAX_SPRITE 100 + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; + +/* Sprite structure */ +typedef struct { + int X, Y; /* Sprite coordinates */ + int DX,DY; /* Deltas for sprite movement */ + int W, H; /* Sprite width and height */ + byte Image[16,16]; /* Sprite image data */ +} TSprite; + +/* RGB color structure */ +typedef struct { + byte R, G, B; +} TRgb; +Tsprite S[MAX_SPRITE]; /* An array of sprites */ +TRgb Palette[ byte ]; /* Palette */ +word Page; /* Page offset */ +word i; + +/* Initializes a sprite structure */ +void sxInit(TSprite *S) +{ +//word i; + +S->X = rand( 320 ); /* Initialize position with random values */ +S->Y = rand( 240 ); +S->DX = rand( 7 )-3; /* Initialize speed with random values */ +S->DY = rand( 7 )-3; +S->W = 16; /* Size is fixed in this program */ +S->H = 16; +/* The image is a square with a hole inside */ +FillChar( S->Image, SizeOf(S->Image), rand(15)+1 ); + for(i=5; i<=12;i++) + { + FillChar( S->Image[ i, 5 ], 8, 0 ); + } +} + +/* Moves a sprite */ +void sxMove(TSprite *S) +{ +//Inc( S.X, S.DX ); /* Get new position */ +//Inc( S.Y, S.DY ); +/* Check sprite position, change delta if needed */ +if( S->X > 320 ){ + S->X = 320; +S->DX = -S->DX; +} +if( S->X < -16 ){ + S->X = -16; +S->DX = -S->DX; +} +if( S->Y > 240 ){ + S.Y = 240; + S->DY = -S->DY; +} +if( S->Y < -16 ){ + S->Y = -16; + S->DY = -S->DY; +} +/* Draw the sprite, note the Page offset added to the */ +/* Y coordinate of the image */ +mxPutImage( S.Image, S->X, Page+S->Y, S->W, S->H, OP_TRANS ); +} + +void main() +{ + int i; + //TSprite S; + /* Initialize library */ + mxInit(); + + /* Enter graphics mode */ + mxSetMode( MX_320x240 ); + + /* Print initialization message */ + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + /* Initialize sprites */ + for(i=1;i<=MAX_SPRITE;i++) + sxInit( &S[i] ); + + /* Draw background */ + for(i=1;i<=192;i++) + { + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + } + + /* Compute and set palette */ + for(i=1;i<= 192;Palette[i+63]) + { + short R = 0; + short G = 0; + short B = 0; + if( i < 64 ) + R = i >> 1+31; + else if( i < 128 ) + G = (i-64) >> 1+31; + else + B = (i-128) >> 1+31; + } + mxSetPalette( @Palette[64], 64, 192 ); + + /* Main loop */ + short Page = 240; + while(!kbhit()) + { + /* Set clip region to current page */ + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + /* Restore background */ + mxBitBlt( 0, 480, 320, 240, 0, Page ); + /* Draw sprites */ + for(i=1; i <= MAX_SPRITE; sxMove( S[i] )); + /* Print message */ + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + /* Flip page */ + mxStartLine( Page ); + Page = 240-Page; + /* Animate palette */ + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + } + + mxSetMode( MX_TEXT ); + mxTerm; + +} diff --git a/16/xw/mxbb.asm b/16/xw/mxbb.asm new file mode 100755 index 00000000..ed24a27c --- /dev/null +++ b/16/xw/mxbb.asm @@ -0,0 +1,278 @@ +;----------------------------------------------------------- +; +; MXBB.ASM - Bit block transfer +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +;WARN PRO +;NOWARN RES +INCLUDE modex.def + +PUBLIC mxBitBlt + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN subHorizontalLineInfo : NEAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves a block of video memory. +; +; Input: +; SX, SY = source coordinates +; Width = source width +; Height = source height +; DX, DY = destination coordinates +; Output: +; none +; +; Note: overlapping regions are not allowed. +; +mxBitBlt PROC FAR + ARG DestY:WORD, \ + DestX:WORD, \ + Height:WORD, \ + Width:WORD, \ + SY:WORD, \ + SX:WORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + SourceOffset:WORD, \ + DestOffset:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + WritePlane:BYTE, \ + LeftMask:BYTE, \ + RightMask:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + +; Exit now if null width + cmp [Width], 0 + je @@Exit + +; Calls the proper procedure to handle transfer + mov ax, [SX] + and al, 03h ; AL = source plane + mov dx, [DestX] + and dl, 03h ; DL = destination plane + mov bx, OFFSET subPlaneBlt + cmp al, dl ; Same source and destination plane? + jne @@BitBlt ; No, use slow procedure + mov bx, OFFSET subMoveBlt +@@BitBlt: + call bx + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; Uses write mode 1 for maximum speed. Only works if source +; and destination are plane-aligned. +; +subMoveBlt PROC NEAR +; Get horizontal line info and address of destination + mov bx, [DestX] + mov ax, [DestY] + mov cx, [Width] + call subHorizontalLineInfo + mov [LeftMask], al + mov [RightMask], ah + mov [Width], cx + +; Setup segments + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + +; Get address of source pixel + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + .shr si, 2 + add si, ax + +; Set write mode 1 + mov dx, GDC + mov ax, 4105h + out dx, ax + cld + +; Move left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] + .push si, di +@@L1: + movsb + add si, ax + add di, ax + dec cx + jnz @@L1 + .pop si, di + inc si + inc di + +; Move center block +@@C0: + mov bx, [Width] + test bx, bx + jz @@R0 + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov ax, [mx_BytesPerLine] + sub ax, bx + mov dx, [Height] + .push si, di +@@C1: + mov cx, bx ; CX = image width + rep movsb ; Cannot use "movsw" here! + add si, ax ; Next scan line + add di, ax ; Next scan line + dec dx ; All lines processed? + jnz @@C1 ; No, continue + .pop si, di + add si, bx + add di, bx + +; Move right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov ax, [mx_BytesPerLine] + dec ax + mov cx, [Height] +@@R1: + movsb + add si, ax + add di, ax + dec cx + jnz @@R1 + +@@Done: + mov dx, GDC + mov ax, 4005h + out dx, ax ; Restore write mode 0 + +@@Exit: + ret +subMoveBlt ENDP + +;----------------------------------------------------------- +; Moves one plane at a time. +; +subPlaneBlt PROC NEAR +; Compute extra bytes and width count for each plane + mov cx, [Width] + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Get pixel addresses + mov ax, [mx_VideoSegment] + mov ds, ax + mov es, ax + mov ax, [SY] + mul [mx_BytesPerLine] + mov si, [SX] + shr si, 1 + shr si, 1 + add si, ax ; DS:SI points to source + mov [SourceOffset], si + mov ax, [DestY] + mul [mx_BytesPerLine] + mov di, [DestX] + shr di, 1 + shr di, 1 + add di, ax ; ES:DI points to destination + mov [DestOffset], di + +; Adjust plane for output to VGA registers + mov ax, [SX] + and al, 03h + mov [ReadPlane], al + mov cx, [DestX] + and cl, 03h + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Ready to move now + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 + je @@Done + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov ax, [mx_BytesPerLine] + sub ax, ss:[bx] ; AX = extra bytes per line +@@Loop: + mov cx, ss:[bx] + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb + add si, ax + add di, ax + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + and [ReadPlane], 03h ; Should be faster on 386 using + jnz @@ReadPlaneOk ; BTR and ADC... + inc [SourceOffset] +@@ReadPlaneOk: + rol [WritePlane], 1 + adc [DestOffset], 0 + mov si, [SourceOffset] + mov di, [DestOffset] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Done: + ret +subPlaneBlt ENDP + +mxBitBlt ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxcc.asm b/16/xw/mxcc.asm new file mode 100755 index 00000000..4f78adb9 --- /dev/null +++ b/16/xw/mxcc.asm @@ -0,0 +1,644 @@ +;----------------------------------------------------------- +; +; MXCC.ASM - Fast clip line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC xsubClipLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblGroups LABEL WORD + DW 10, tbl00 + DW 10, tbl10 + DW 9, tbl20 + DW -1, 0 + DW 10, tbl40 + DW 10, tbl50 + DW 9, tbl60 + DW -1, 0 + DW 6, tbl80 + DW 6, tbl90 + DW 5, tblA0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 + DW -1, 0 +tbl00 DW cc00, cc01, cc02, ccFF, cc04, cc05, cc06, ccFF, cc08, cc09, cc0A +tbl10 DW cc10, ccFF, cc12, ccFF, cc14, ccFF, cc16, ccFF, cc18, ccFF, cc1A +tbl20 DW cc20, cc21, ccFF, ccFF, cc24, cc25, ccFF, ccFF, cc28, cc29 +tbl40 DW cc40, cc41, cc42, ccFF, ccFF, ccFF, ccFF, ccFF, cc48, cc49, cc4A +tbl50 DW cc50, ccFF, cc52, ccFF, ccFF, ccFF, ccFF, ccFF, cc58, ccFF, cc5A +tbl60 DW cc60, cc61, ccFF, ccFF, ccFF, ccFF, ccFF, ccFF, cc68, cc69 +tbl80 DW cc80, cc81, cc82, ccFF, cc84, cc85, cc86 +tbl90 DW cc90, ccFF, cc92, ccFF, cc94, ccFF, cc96 +tblA0 DW ccA0, ccA1, ccFF, ccFF, ccA4, ccA5 + +ccTT: clc + ret +ccFF: stc + ret + +; Group 00 ------------------------------------------------- +; +cc00: + clc + ret +cc01: + jmp ClipQLeft +cc02: + jmp ClipQRight +cc04: + jmp ClipQTop +cc05: + call ClipQLeft + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc06: + call ClipQRight + cmp si, [mx_ClipY1] + jge ccTT + jmp ClipQTop +cc08: + jmp ClipQBottom +cc09: + call ClipQLeft + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom +cc0A: + call ClipQRight + cmp si, [mx_ClipY2] + jle ccTT + jmp ClipQBottom + +; Group 10 ------------------------------------------------- +; +cc10FF: + stc + ret +cc10TT: + clc + ret +cc10: + jmp ClipPLeft +cc12: + call ClipPLeft + jmp ClipQRight +cc14: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + jmp ClipQTop +cc16: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc10FF + call ClipQTop + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight +cc18: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + jmp ClipQBottom +cc1A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc10FF + call ClipQBottom + cmp cx, [mx_ClipX2] + jle cc10TT + jmp ClipQRight + +; Group 20 ------------------------------------------------- +; +cc20TT: + clc + ret +cc20FF: + stc + ret +cc20: + jmp ClipPRight +cc21: + call ClipPRight + jmp ClipQLeft +cc24: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + jmp ClipQTop +cc25: + call ClipPRight + cmp bx, [mx_ClipY1] + jl cc20FF + call ClipQTop + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft +cc28: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + jmp ClipQBottom +cc29: + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc20FF + call ClipQBottom + cmp cx, [mx_ClipX1] + jge cc20TT + jmp ClipQLeft + +; Group 40 ------------------------------------------------- +; +cc40TT: + clc + ret +cc40FF: + stc + ret +cc40: + jmp ClipPTop +cc41: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc40TT + jmp ClipQTop +cc42: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + jmp ClipQRight +cc48: + call ClipPTop + jmp ClipQBottom +cc49: + call ClipPTop + cmp di, [mx_ClipX1] + jl cc40FF + call ClipQLeft + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom +cc4A: + call ClipPTop + cmp di, [mx_ClipX2] + jg cc40FF + call ClipQRight + cmp si, [mx_ClipY2] + jle cc40TT + jmp ClipQBottom + + +; Group 50 ------------------------------------------------- +; +cc50TT: + clc + ret +cc50FF: + stc + ret +cc50: + call ClipPLeft + cmp bx, [mx_ClipY1] + jge cc50TT + jmp ClipPTop +cc52: + call ClipQRight + cmp si, [mx_ClipY1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc58: + call ClipQBottom + cmp cx, [mx_ClipX1] + jl cc50FF + call ClipPTop + cmp di, [mx_ClipX1] + jge cc50TT + jmp ClipPLeft +cc5A: + call ClipPLeft + cmp bx, [mx_ClipY2] + jg cc50FF + call ClipQRight + cmp bx, [mx_ClipY1] + jl cc50FF + cmp si, [mx_ClipY2] + jle cc50TT + jmp ClipQBottom + +; Group 60 ------------------------------------------------- +; +cc60TT: + clc + ret +cc60FF: + stc + ret +cc60: + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc61: + call ClipQLeft + cmp si, [mx_ClipY2] + jl cc60FF + call ClipPTop + cmp di, [mx_ClipX2] + jle cc60TT + jmp ClipPRight +cc68: + call ClipQBottom + cmp cx, [mx_ClipX2] + jg cc60FF + call ClipPRight + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop +cc69: + call ClipQLeft + cmp si, [mx_ClipY1] + jl cc60FF + call ClipPRight + cmp bx, [mx_ClipY2] + jg cc60FF + cmp si, [mx_ClipY2] + jle cc69_1 + call ClipQBottom +cc69_1: + cmp bx, [mx_ClipY1] + jge cc60TT + jmp ClipPTop + +; Group 80 ------------------------------------------------- +; +cc80TT: + clc + ret +cc80FF: + stc + ret +cc80: + jmp ClipPBottom +cc81: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + jmp ClipQLeft +cc82: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + jmp ClipQRight +cc84: + call ClipPBottom + jmp ClipQTop +cc85: + call ClipPBottom + cmp di, [mx_ClipX1] + jl cc80FF + call ClipQLeft + cmp si, [mx_ClipY1] + jge cc80FF + jmp ClipQTop +cc86: + call ClipPBottom + cmp di, [mx_ClipX2] + jg cc80FF + call ClipQRight + cmp si, [mx_ClipY1] + jge cc80TT + jmp ClipQTop + +; Group 90 ------------------------------------------------- +; +cc90TT: + clc + ret +cc90FF: + stc + ret +cc90: + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc92: + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + call ClipPBottom + cmp di, [mx_ClipX1] + jge cc90TT + jmp ClipPLeft +cc94: + call ClipQTop + cmp cx, [mx_ClipX1] + jl cc90FF + call ClipPLeft + cmp bx, [mx_ClipY2] + jle cc90TT + jmp ClipPBottom +cc96: + call ClipPLeft + cmp bx, [mx_ClipY1] + jl cc90FF + call ClipQRight + cmp si, [mx_ClipY2] + jg cc90FF + cmp bx, [mx_ClipY2] + jle cc96_1 + call ClipPBottom +cc96_1: + cmp si, [mx_ClipY1] + jge cc90TT + jmp ClipQTop + +; Group A0 ------------------------------------------------- +; +ccA0TT: + clc + ret +ccA0FF: + stc + ret +ccA0: + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA1: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPBottom + cmp di, [mx_ClipX2] + jle ccA0TT + jmp ClipPRight +ccA4: + call ClipQTop + cmp cx, [mx_ClipX2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom +ccA5: + call ClipQLeft + cmp si, [mx_ClipY2] + jg ccA0FF + call ClipPRight + cmp bx, [mx_ClipY1] + jl ccA0FF + cmp si, [mx_ClipY1] + jge ccA5_1 + call ClipQTop +ccA5_1: + cmp bx, [mx_ClipY2] + jle ccA0TT + jmp ClipPBottom + +; Y1 = (Y2-Y1)*(mx_ClipX1-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX1-DI)/(CX-DI)+BX +; X1 = mx_ClipX1 +ClipPLeft: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX1] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX1] + clc + ret + +; Y1 = (Y2-Y1)*(mx_ClipX2-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX2-DI)/(CX-DI)+BX +; X1 = mx_ClipX2 +ClipPRight: + mov ax, si + sub ax, bx + mov dx, [mx_ClipX2] + sub dx, di + imul dx + mov bp, cx + sub bp, di + idiv bp + add bx, ax + mov di, [mx_ClipX2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY2-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY2-BX)/(SI-BX)+DI +; Y1 = mx_ClipY2 +ClipPBottom: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY2] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY2] + clc + ret + +; X1 = (X2-X1)*(mx_ClipY1-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY1-BX)/(SI-BX)+DI +; Y1 = mx_ClipY1 +ClipPTop: + mov ax, cx + sub ax, di + mov dx, [mx_ClipY1] + sub dx, bx + imul dx + mov bp, si + sub bp, bx + idiv bp + add di, ax + mov bx, [mx_ClipY1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX1-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX1-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQLeft: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX1] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX1] + clc + ret + +; Y2 = (Y1-Y2)*(mx_ClipX2-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX2-CX)/(DI-CX)+SI +; X2 = mx_ClipX1 +ClipQRight: + mov ax, bx + sub ax, si + mov dx, [mx_ClipX2] + sub dx, cx + imul dx + mov bp, di + sub bp, cx + idiv bp + add si, ax + mov cx, [mx_ClipX2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY2-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY2-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQBottom: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY2] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY2] + clc + ret + +; X2 = (X1-X2)*(mx_ClipY1-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY1-SI)/(BX-SI)+CX +; Y2 = mx_ClipY1 +ClipQTop: + mov ax, di + sub ax, cx + mov dx, [mx_ClipY1] + sub dx, si + imul dx + mov bp, bx + sub bp, si + idiv bp + add cx, ax + mov si, [mx_ClipY1] + clc + ret + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses the Sobkow-Pospisil-Yang (SPY) algorithm: this was +; supposed to be twice as fast as Cohen-Sutherland, but my +; tests show only a very small increase in speed and a noticeable +; increase of the program size! Maybe this is caused by the +; slow speed of VGA cards, so probably a better test should +; be performed with lines drawn in RAM. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +xsubClipLine PROC NEAR + push bp + xor si, si ; SPY code + + cmp dx, [mx_ClipY2] + jle @@1 + or si, 08h + jmp @@2 +@@1: + cmp dx, [mx_ClipY1] + jge @@2 + or si, 04h +@@2: + + cmp cx, [mx_ClipX2] + jle @@3 + or si, 02h + jmp @@4 +@@3: + cmp cx, [mx_ClipX1] + jge @@4 + or si, 01h +@@4: + + cmp bx, [mx_ClipY2] + jle @@5 + or si, 80h + jmp @@6 +@@5: + cmp bx, [mx_ClipY1] + jge @@6 + or si, 40h +@@6: + + cmp ax, [mx_ClipX2] + jle @@7 + or si, 20h + jmp @@8 +@@7: + cmp ax, [mx_ClipX1] + jge @@8 + or si, 10h +@@8: + + mov di, si + and di, 000Fh ; Index of procedure + and si, 00F0h + .shr si, 2 ; Index of group (times 4) + cmp di, cs:tblGroups[si] ; Is index within range? + jg @@Exit ; No, line is full clipped + mov si, cs:tblGroups[si+2] ; Get offset of group table + shl di, 1 ; We must index word elements + add si, di ; Make full offset + mov di, ax ; Move X1 to DI and free AX + mov si, cs:[si] ; Get subroutine address + xchg dx, si ; Move Y2 to SI and free DX + call dx ; Call the proper subroutine + mov ax, di ; Restore AX to X1 + mov dx, si ; Restore DX to Y2 + pop bp + ret + +@@Exit: + pop bp + stc + ret +xsubClipLine ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxcg.asm b/16/xw/mxcg.asm new file mode 100755 index 00000000..42163d7a --- /dev/null +++ b/16/xw/mxcg.asm @@ -0,0 +1,69 @@ +;----------------------------------------------------------- +; +; MXCG.ASM - Color to gray conversion +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxColorToGray + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Converts RGB colors to gray shades. +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gray) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxColorToGray PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit + lds si, [SPal] + les di, [DPal] + cld +; We use the standard formula +; gray=(red*30 + green*59 + blue*11)/100 +; in the equivalent form +; gray=(red*77 + green*151 + blue*28)/256 +; which doesn't need the last divide. + mov bx, 77 SHL 8 + 151 +@@Loop: + lodsb ; Red + mul bh + mov dx, ax + lodsb ; Green + mul bl + add dx, ax + lodsb ; Blue + mov ah, 28 + mul ah + add ax, dx + mov al, ah + stosw ; Save new RGB + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxColorToGray ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxcl.asm b/16/xw/mxcl.asm new file mode 100755 index 00000000..aaa0bac3 --- /dev/null +++ b/16/xw/mxcl.asm @@ -0,0 +1,151 @@ +;----------------------------------------------------------- +; +; MXCL.ASM - Bresenham circle +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxCircle + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws a circle using the Bresenham algorithm. +; +; Input: +; XC, YC = center coordinates +; Radius = circle radius +; Color = circle color +; Output: +; none +; Note: +; computes only points in the first octant, all other +; points are obtained by symmetry. +; +mxCircle PROC FAR + ARG Color:BYTE:2, \ + Radius:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL Delta:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + xor si, si ; X + mov di, [Radius] ; Y + mov ax, 3 + sub ax, di + sub ax, di + mov [Delta], ax ; Delta = 3-R*2 + + mov ds, [mx_VideoSegment] + +@@Loop: + cmp si, di ; + jg @@Done ; Exit when X > Y +; Draw points + mov ax, si + mov bx, di + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + call @@subPutPixel + mov ax, si + mov bx, di + neg bx + call @@subPutPixel + mov ax, si + neg ax + mov bx, di + neg bx + call @@subPutPixel + mov ax, di + mov bx, si + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + call @@subPutPixel + mov ax, di + mov bx, si + neg bx + call @@subPutPixel + mov ax, di + neg ax + mov bx, si + neg bx + call @@subPutPixel +; Moves coordinates to next point + mov ax, [Delta] + test ax, ax + jl @@Next + mov ax, di + .shl ax, 2 + sub ax, 4 + sub [Delta], ax + dec di +@@Next: + mov ax, si + .shl ax, 2 + add ax, 6 + add [Delta], ax + inc si + jmp @@Loop + +@@Done: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;--------------------------------------- +; Put pixel function. +; Input: +; BX = X coordinate (relative to center) +; AX = Y coordinate (relative to center) +; DS = video segment +@@subPutPixel: + add bx, [XC] ; Get absolute coordinates + add ax, [YC] + + cmp bx, [mx_ClipX1] ; Clip pixel + jl @@subExit + cmp bx, [mx_ClipX2] + jg @@subExit + cmp ax, [mx_ClipY1] + jl @@subExit + cmp ax, [mx_ClipY2] + jg @@subExit + + mul [mx_BytesPerLine] ; Get pixel offset + mov cx, bx ; Save X coordinate + .shr bx, 2 + add bx, ax ; DS:BX = pixel offset + + and cl, 3 ; Set write plane + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[bx], al + +@@subExit: + retn +mxCircle ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxcr.asm b/16/xw/mxcr.asm new file mode 100755 index 00000000..ca1fa7bb --- /dev/null +++ b/16/xw/mxcr.asm @@ -0,0 +1,380 @@ +;----------------------------------------------------------- +; +; MXCR.ASM - Clip functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetSysClipRegion +PUBLIC mxGetClipRegion +PUBLIC mxSetClipRegion +PUBLIC mxSetClip +PUBLIC mxGetClip + +PUBLIC subClipBox +PUBLIC subClipImage + +PUBLIC mx_ClipX1 +PUBLIC mx_ClipY1 +PUBLIC mx_ClipX2 +PUBLIC mx_ClipY2 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD + +mx_ClipX1 DW ? ; Clip coordinates +mx_ClipY1 DW ? +mx_ClipX2 DW ? +mx_ClipY2 DW ? + +mx_SysClipX1 DW ? ; System clip coordinates +mx_SysClipY1 DW ? ; (active when mx_ClipStatus is FALSE) +mx_SysClipX2 DW ? +mx_SysClipY2 DW ? + +mx_UserClipX1 DW ? ; User clip coordinates +mx_UserClipY1 DW ? ; (active when mx_ClipStatus is TRUE) +mx_UserClipX2 DW ? +mx_UserClipY2 DW ? + +mx_ClipStatus DB ? + +;----------------------------------------------------------- +; +; Toggles clipping between user and system regions. +; +; Input: +; ClipStatus = TRUE (FALSE) to enable (disable) clipping +; Output: +; AX = old clip status +; +mxSetClip PROC FAR + ARG ClipStatus:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [mx_UserClipX1] + mov bx, [mx_UserClipY1] + mov cx, [mx_UserClipX2] + mov dx, [mx_UserClipY2] + cmp [ClipStatus], TRUE + je @@Done + mov ax, [mx_SysClipX1] + mov bx, [mx_SysClipY1] + mov cx, [mx_SysClipX2] + mov dx, [mx_SysClipY2] +@@Done: + mov [mx_ClipX1], ax + mov [mx_ClipY1], bx + mov [mx_ClipX2], cx + mov [mx_ClipY2], dx + + mov al, [ClipStatus] + xchg al, [mx_ClipStatus] + xor ah, ah + + .pop ds + .leave ARG_SIZE +mxSetClip ENDP + +;----------------------------------------------------------- +; +; Returns the current clipping status. +; +; Input: +; none +; Output: +; TRUE (FALSE) if clipping enabled (disabled) +; +mxGetClip PROC FAR + ASSUME ds:NOTHING + mov al, [mx_ClipStatus] + xor ah, ah + ret +mxGetClip ENDP + +;----------------------------------------------------------- +; +; Sets the system clip region and disables user clipping. +; +; Input: +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; old clip status. +; +mxSetSysClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + xor ax, ax ; Sys clip region always starts at (0,0) + mov [mx_SysClipX1], ax + mov [mx_SysClipY1], ax + mov ax, [Width] + dec ax + mov [mx_SysClipX2], ax + mov ax, [Height] + dec ax + mov [mx_SysClipY2], ax + + IF USE286 EQ TRUE + push FALSE + ELSE + mov ax, FALSE + push ax + ENDIF + call mxSetClip + + .pop ds + .leave ARG_SIZE +mxSetSysClipRegion ENDP + +;----------------------------------------------------------- +; +; Sets the clip region. +; +; Input: +; X, Y = coordinates of top left corner of clip region +; Width = width in pixels of clip region +; Height = height in pixels of clip region +; Output: +; none (no checking on parameters) +; +mxSetClipRegion PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [X] + mov [mx_UserClipX1], ax + mov ax, [Y] + mov [mx_UserClipY1], ax + mov ax, [Width] + add ax, [X] + dec ax + mov [mx_UserClipX2], ax + mov ax, [Height] + add ax, [Y] + dec ax + mov [mx_UserClipY2], ax + + mov al, [mx_ClipStatus] + cmp al, TRUE + jne @@Exit + push ax + call mxSetClip + +@@Exit: + xor ax, ax + .pop ds + .leave ARG_SIZE +mxSetClipRegion ENDP + +;----------------------------------------------------------- +; +; Returns the current user clip region. +; +; Input: +; X, Y = pointers to integer coordinates of top left corner +; Width = pointer to word width of clip region +; Height = pointer to word height of clip region +; Output: +; AX = current clip status +; +mxGetClipRegion PROC FAR + ARG Height:DWORD, \ + Width:DWORD, \ + Y:DWORD, \ + X:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + mov ax, [mx_UserClipX1] + les di, [X] + mov es:[di], ax + mov ax, [mx_UserClipY1] + les di, [Y] + mov es:[di], ax + + mov ax, [mx_UserClipX2] + sub ax, [mx_UserClipX1] + inc ax + les di, [Width] + mov es:[di], ax + mov ax, [mx_UserClipY2] + sub ax, [mx_UserClipY1] + inc ax + les di, [Height] + mov es:[di], ax + + mov al, [mx_ClipStatus] + xor ah, ah + .pop es, di + .leave ARG_SIZE +mxGetClipRegion ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; This function assumes that a "raw" image has to be clipped, +; so it returns in SI the number of "raw" bytes to skip if +; X, Y were clipped. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; SI = number of bytes to skip before copying a buffer +; DI destroyed +; +subClipImage PROC NEAR + ASSUME ds:NOTHING + xor si, si + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, di + mov di, dx ; Save box height into DI + mul cx ; DX:AX = number of bytes to skip + mov si, ax + mov dx, di ; Restore box height + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax + jge @@DoneHeight ; None, continue + add dx, di ; Clip lines +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + add si, di ; Update skip count + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx + jge @@DoneWidth ; None, exit + add cx, di ; New box width +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipImage ENDP + +;----------------------------------------------------------- +; +; Internal use: checks the coordinates of a rectangle against +; the active clip region. +; +; Input: +; BX, AX = X, Y coordinates of rectangle (signed) +; CX = box width +; DX = box height +; Output: +; CF = set if rectangle is full clipped +; BX, AX = new X, Y coordinates of rectangle +; CX, DX = clipped width and height +; DI destroyed +; +subClipBox PROC NEAR + ASSUME ds:NOTHING + +; Check clip height + mov di, [mx_ClipY1] + cmp ax, di + jge @@CheckBottom + sub di, ax ; Number of lines to clip + sub dx, di ; New box height + jle @@Exit + mov ax, [mx_ClipY1] +@@CheckBottom: + mov di, [mx_ClipY2] + cmp ax, di + jg @@Exit + inc di + sub di, dx + sub di, ax ; Clipped some point? + jge @@DoneHeight ; No, continue + add dx, di ; Clip lines (DI is negative) +@@DoneHeight: + +; Check clip width +@@CheckLeft: + mov di, [mx_ClipX1] + cmp bx, di + jge @@CheckRight + sub di, bx ; Number of columns to clip left + sub cx, di + jle @@Exit + mov bx, [mx_ClipX1] +@@CheckRight: + mov di, [mx_ClipX2] + cmp bx, di + jg @@Exit + inc di + sub di, bx + sub di, cx ; Clipped some point? + jge @@DoneWidth ; No, exit + add cx, di ; New box width (DI is negative) +@@DoneWidth: + +; Set return flag and exit +@@Done: + clc + ret +@@Exit: + stc + ret +subClipBox ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxel.asm b/16/xw/mxel.asm new file mode 100755 index 00000000..2c9dda2a --- /dev/null +++ b/16/xw/mxel.asm @@ -0,0 +1,167 @@ +;----------------------------------------------------------- +; +; MXEL.ASM - Mid-point ellipse +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxEllipse + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Draws an ellipse using the mid-point algorithm. +; +; Input: +; XC, YC = center coordinates +; A = horizontal radius +; B = vertical radius +; Color = ellipse color +; Output: +; none +; Note: +; computes only points in the first quadrant, all other +; points are obtained by symmetry. +; +mxEllipse PROC FAR + ARG Color:BYTE:2, \ + B:WORD, \ + A:WORD, \ + YC:WORD, \ + XC:WORD = ARG_SIZE + LOCAL A2:DWORD, \ + B2:DWORD, \ + CC:DWORD, \ + DD:DWORD, \ + X:DWORD, \ + Y:DWORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + + .chk386 mxEllipse, @@Exit + +; Initialize variables + xor eax, eax + mov [X], ax ; X = 0 + mov ax, [A] + mul eax ; EAX = A*A + mov [DD], eax ; DD = A*A + shl eax, 1 + mov [CC], eax ; CC = 2*A*A + shl eax, 1 + mov [A2], eax ; A2 = 4*A*A + movzx edx, [B] + mov [Y], edx + mul edx ; EAX = 4*A*A*B + sub [DD], eax ; DD = A*A - 4*A*A*B + movzx eax, [B] + mul eax ; EAX = B*B + shl eax, 2 ; EAX = 4*B*B + mov [B2], eax ; B2 = 4*B*B + add [CC], eax ; CC = 2*A*A + 4*B*B + add [D1], eax ; DD = A*A - 4*A*A*B + 4*B*B + +; Draw initial points + call subPlot4 + +; First loop +@@Loop1: + mov eax, [X] ; Check slope + mul [B2] + mov ecx, eax + mov eax, [Y] + mul [A2] + sub eax, ecx + sub eax, [CC] ; EAX = Y*A2 - X*B2 - CC + jle @@Done1 ; Crossed critical point, jump to next loop + + mov ecx, [DD] ; Get error + test ecx, ecx ; Positive? + jl @@Draw1 ; No, use default step + + mov eax, 1 + sub eax, [Y] + mul [A2] + shl eax, 1 + add ecx, eax ; Bump error + dec WORD PTR [Y] ; Decrement Y coordinate + +@@Draw1: + mov eax, [X] + shl eax, 1 + add eax, 3 + mul [B2] + add ecx, eax ; Bump error + mov [DD], ecx ; Save error + inc WORD PTR [X] ; Increment X coordinate + + call subPlot4 ; Draw points + jmp @@Loop1 +@@Done1: + +; Initialize variables + shr [B2], 2 + mov eax, [X] + mul eax + add [X] + shl eax, 2 + inc eax + mul [B2] + mov [DD], eax + mov eax, [Y] + mul eax + add [Y] + dec eax + add [Y] + sub eax, [B2] + add [DD], eax + shl [B2], 3 + inc WORD PTR [X] + +; Second loop +@@Loop2: + cmp WORD PTR [Y], 0 + ja @@Done2 + + mov ecx, [DD] + test ecx, ecx + jge @@Draw2 + + mov eax, [X] + inc eax + mul [B2] + add ecx, eax + inc WORD PTR [X] + +@@Draw2: + mov eax, [Y] + shl eax, 1 + sub eax, 3 + neg eax + imul [A2] + add ecx, eax + dec WORD PTR [Y] + + call subPlot4 + jmp @@Loop2 +@@Done2: + +@@Exit: + xor ax, ax + .leave ARG_SIZE +mxEllipse ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxfb.asm b/16/xw/mxfb.asm new file mode 100755 index 00000000..41ea5deb --- /dev/null +++ b/16/xw/mxfb.asm @@ -0,0 +1,194 @@ +;----------------------------------------------------------- +; +; MXFB.ASM - Fill box function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillBox + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN subClipBox : NEAR +EXTRN subHorizontalLineInfo : NEAR + +;----------------------------------------------------------- +; +; Raster op functions. Raster op is limited to OP_MOVE, +; OP_AND, OP_OR and OP_XOR. The VGA hardware is used to +; perform the selected logical functions on up to four +; pixel at a time. +; +subRepFill PROC NEAR + mov ah, al + shr cx, 1 + rep stosw + rcl cx, 1 + rep stosb + ret +subRepFill ENDP +; +subFill PROC NEAR +@@Loop: + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subFill ENDP +; +subRepMove PROC NEAR + mov si, di +@@Loop: + mov ah, ds:[si] ; Dummy read to latch the data + mov ds:[si], al + inc si + loop @@Loop + ret +subRepMove ENDP +; +subMove PROC NEAR +@@Loop: + mov ah, ds:[bx] ; Dummy read to latch the data + mov ds:[bx], al + add bx, dx + loop @@Loop + ret +subMove ENDP + +;----------------------------------------------------------- +; +; Fills a rectangle with a specified color. +; +; Input: +; X, Y = X, Y coordinates of rectangle +; Width = width of rectangle +; Height = height of rectangle +; Color = fill color +; Op = raster operator +; Output: +; none +; +; Note: raster op is limited to OP_MOVE, OP_AND, OP_OR and OP_XOR. +; +mxFillBox PROC FAR + ARG Op:WORD, \ + Color:BYTE:2, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL LeftMask:BYTE, \ + RightMask:BYTE, \ + FillFunction:WORD, \ + RepFillFunction:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Clip rectangle + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipBox + jc @@Exit ; Full clipped + + mov [Height], dx ; Save clipped height + call subHorizontalLineInfo ; Get additional info, init DI + mov [Width], cx + mov [LeftMask], al + mov [RightMask], ah + +; Initialize segments + mov ax, [mx_VideoSegment] + mov es, ax ; ES:DI points to pixel + mov ds, ax + cld ; Clear direction flag + +; Select fill functions + mov [FillFunction], OFFSET subFill + mov [RepFillFunction], OFFSET subRepFill + mov ax, [Op] ; Get raster op + cmp al, OP_XOR + ja @@1 ; Assume it's a fill + cmp al, OP_MOVE + je @@1 + .shl al, 3 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set GDC logical function + mov [FillFunction], OFFSET subMove + mov [RepFillFunction], OFFSET subRepMove +@@1: + +; Fill left block +@@L0: + mov ah, [LeftMask] + or ah, ah + jz @@C0 ; Nothing to do, go to center block + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + inc di ; Update starting video offset + +; Fill center block +@@C0: + mov cx, [Width] + jcxz @@R0 ; Nothing to do, go to right block + mov dx, TS + mov ax, 0F02h + out dx, ax ; Write to all planes + mov al, [Color] + mov bx, di + mov dx, [Height] + push di ; Save pixel address +@@C1: + mov di, bx ; Update video offset + call [RepFillFunction] ; Fill current scan line + mov cx, [Width] ; Restore byte count + add bx, [mx_BytesPerLine] ; Bump to next scan line + dec dx ; Done all lines? + jnz @@C1 ; No, continue + pop di ; Restore pixel address + add di, [Width] ; Go to right block + +; Fill right block +@@R0: + mov ah, [RightMask] + or ah, ah + jz @@Done ; Nothing to do, exit + mov dx, TS + mov al, 02h + out dx, ax ; Set write plane mask + mov dx, [mx_BytesPerLine] + mov cx, [Height] + mov bx, di + mov al, [Color] + call [FillFunction] ; Fill this column + +; Restore VGA registers +@@Done: + mov dx, GDC + mov ax, 0003h + out dx, ax ; Set logical function to "move" + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillBox ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxfp.asm b/16/xw/mxfp.asm new file mode 100755 index 00000000..8eea25be --- /dev/null +++ b/16/xw/mxfp.asm @@ -0,0 +1,326 @@ +;----------------------------------------------------------- +; +; MXFP.ASM - Fade palette function +; Copyright (c) 1992-1994 ARTIS s.r.l. +; Author: Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxFadePalette + +MAXCOLOR EQU 256 +FADE_IN EQU 0 +FADE_OUT EQU 1 + +; The actual speed of fading depends on the number of passes (FADE_SPEED) and +; the delay between two consecutive passes (FADE_DELAY). Below are the +; default values, used when no parameters are specified. +; +FADE_DELAY EQU 1 ; Vert. retraces between video updates +FADE_SPEED EQU 48 ; Speed of effect (max 127) + +; Bit field record for fade commands +; +FADE_COMMAND RECORD fpDELAY:8,fpSPEED:7,fpDIRECTION:1 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'Copyright (c) 1992-1994 ARTIS s.r.l. All rights reserved.' + +;----------------------------------------------------------- +; +; Fades a VGA palette. +; +; Input: +; Buffer = pointer to source/destination palette +; Command = fading direction and optional parameters +; Start = index of first color to fade +; Count = number of color to fade +; Red = destination red +; Green = destination green +; Blue = destination blue +; Output: +; none +; Notes: +; - about 1.5 Kbytes of stack space are needed for internal buffers; +; - the Command argument usually is 0 to fade in and 1 to fade out, +; however additional parameters may be specified. To set the effect +; speed, i.e. the number of iterations needed to completely fade a +; palette, shift the value one bit left and "or" it with the +; direction bit (range is 0..127). To set the delay between two +; consecutive passes, shift it eight bits left (range is 0..255). +; +mxFadePalette PROC FAR + ARG bBlue:WORD, \ + bGreen:WORD, \ + bRed:WORD, \ + wCount:WORD, \ + wStartIdx:WORD, \ + wCommand:WORD, \ + vfpPalette:DWORD = ARG_SIZE + LOCAL bSPalette:BYTE:MAXCOLOR*3, \ + bDPalette:BYTE:MAXCOLOR*3, \ + bLoopIndex:BYTE, \ + bLoopStep:BYTE, \ + bLoopCount:BYTE, \ + wDelay:WORD, \ + wSpeed:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push si, di, ds, es ; Save registers +; +; Check parameters and setup variables +; +@@GetDelay: + mov [wDelay], FADE_DELAY ; Set default delay + mov ax, [wCommand] ; Get command word + and ax, MASK fpDELAY ; Mask delay command + jz @@GetSpeed ; No command, get speed + IF USE286 EQ TRUE + shr ax, fpDELAY + ELSE + mov cl, fpDELAY ; Get size of delay field + shr ax, cl ; Right justify the field + ENDIF + mov [wDelay], ax ; Set new delay + +@@GetSpeed: + mov ax, [wCommand] ; Get command + and ax, MASK fpSPEED ; Mask speed + IF USE286 EQ TRUE + shr ax, fpSPEED + ELSE + mov cl, fpSPEED ; Get size of speed field + shr ax, cl ; Right justify the field + ENDIF + or ax, ax ; Any speed specified? + jnz @@SetVariables ; Yes, set variables + mov ax, FADE_SPEED ; Set default speed + +@@SetVariables: + mov [wSpeed], ax ; Set speed + inc ax ; Number of iterations + mov [bLoopCount], al ; Set loop count + mov [bLoopStep], 1 ; Assume we're fading in + mov [bLoopIndex], 0 +; +; Check bounds for bad values +; + mov ax, [wStartIdx] ; Get first index + cmp ax, MAXCOLOR ; Is in the valid range? + jae @@Exit ; No, exit + add ax, [wCount] ; Get last index + cmp ax, MAXCOLOR ; Is in the valid range? + jbe @@BoundsOk ; Yes, continue + mov ax, MAXCOLOR + sub ax, [wStartIdx] + mov [wCount], ax ; Set count to maximum value + or ax, ax + jz @@Exit ; Nothing to do, exit +@@BoundsOk: +; +; Copy the source palette in a local array: if we fade in it's ready to +; use, otherwise we'll overwrite it later +; + mov cx, [wCount] + mov ax, cx + shl ax, 1 + add cx, ax ; CX = wCount * 3 + mov ax, ss + mov es, ax + lea di, [bSPalette] ; ES:DI points to local palette + mov ax, [wStartIdx] + mov si, ax + shl ax, 1 + add ax, si + lds si, [vfpPalette] ; DS:SI points to user palette + add si, ax ; Skip unused entries + cld + shr cx, 1 + rep movsw + rcl cx, 1 + rep movsb +; +; Check direction +; + test [wCommand], MASK fpDIRECTION ; Are we fading in? + jz @@Main ; Yes, ok to continue + mov ax, [wSpeed] ; Get speed + mov [bLoopIndex], al ; Exchange first and last index + mov [bLoopStep], -1 ; Move backward + mov ax, ss ; Overwrite our copy of + mov ds, ax ; user palette with the + mov es, ax ; current active palette + lea di, [bSPalette] + mov ax, [wStartIdx] + mov cx, [wCount] + call ReadPalette ; Read current palette +; +; Prepare variables and registers for fading +; +@@Main: + mov bh, BYTE PTR [bRed] ; Destination red + and bh, 00111111b ; Be sure it's a valid VGA value + mov bl, BYTE PTR [bGreen] ; Destination green + and bl, 00111111b ; Be sure it's a valid VGA value + mov dh, BYTE PTR [bBlue] ; Destination blue + and dh, 00111111b ; Be sure it's a valid VGA value + mov dl, [bLoopIndex] ; Loop index + mov ax, ss ; All tables are stored + mov ds, ax ; in the stack segment, + mov es, ax ; set DS and ES +; +; Main loop +; +@@Loop: + mov ax, [wCount] ; Store count in AX + mov cx, [wSpeed] ; Set maximum speed in CX + lea si, [bSPalette] ; DS:SI points to source palette + lea di, [bDPalette] ; ES:DI points to dest. palette + call RecalcPalette ; Build a faded palette + + .push bx, dx ; Save registers we need + lea si, [bDPalette] ; DS:SI points to palette + mov ax, [wStartIdx] ; First index to write + mov bx, [wCount] ; Total entries to write + mov cx, [wDelay] ; Fade delay between updates + call WritePalette ; Write palette + .pop bx, dx ; Restore BX and DX + + add dl, [bLoopStep] ; Change fade intensity + dec [bLoopCount] ; Done? + jnz @@Loop ; No, loop again + +@@Exit: + .pop si, di, ds, es ; Restore registers + .leave ARG_SIZE +mxFadePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Calculates a partially faded palette. +; +; Input: +; AX = number of entries in palette +; CX = maximum fade intensity (same as fade speed) +; DS:SI = pointer to source palette +; ES:DI = pointer to destination palette +; BH = destination red +; BL = destination green +; DH = destination blue +; DL = relative intensity of destination palette +; Note: +; it's important that a new palette can be calculated in less +; than 1/70th of second. Fading to any RGB value requires use +; of "imul" instructions: "idiv" may be replaced with faster +; "sar", but only when the number of passes is a power of two, +; thus reducing the range of selectable speeds. +; In both cases an extimate of CPU cycles required by this +; procedure shows that it's too slow to run on a 4.77 Mhz 8086 +; CPU and a 256 color palette, so we keep "idiv" and hope +; the target machine to be at least a 6 Mhz 80286 (that's not +; asking too much...). +; +RecalcPalette PROC NEAR + cld + push bp ; Save BP + mov bp, ax ; Copy counter in BP +@@Loop: + lodsb ; Red: read value + sub al, bh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bh ; Add destination value... + stosb ; ...and store it + lodsb ; Green: read value + sub al, bl ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, bl ; Add destination value... + stosb ; ...and store it + lodsb ; Blue: read value + sub al, dh ; Subtract destination value + imul dl ; Scale to desired weight + idiv cl ; Put value in AL + add al, dh ; Add destination value... + stosb ; ...and store it + dec bp + jnz @@Loop + pop bp ; Restore BP + ret +RecalcPalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Writes a 256 color palette. +; +; Input: +; AX = index of first color to write +; BX = number of colors to write (each color is an RGB triplet) +; CX = number of vertical retraces to wait before writing to DACs +; DS:SI = pointer to first entry of palette +; +WritePalette PROC NEAR + ASSUME ds:NOTHING + mov ah, al ; Save index + mov dx, 03DAh ; Input status register +@@Delay1: + in al, dx + test al, 08h + jnz @@Delay1 ; Wait for display mode +@@Delay2: + in al, dx + test al, 08h + jz @@Delay2 ; Wait for vertical retrace mode + loop @@Delay1 ; Repeat CX times +@@Write: + mov cx, bx ; Get number of colors + mov dx, 03C8h ; PEL write address register + mov al, ah ; Restore index + out dx, al ; Select index of first color + inc dx ; PEL data register + cld ; Move forward + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + ret +WritePalette ENDP + +;------- INTERNAL USE ONLY ------------------------------------------------ +; +; Reads the current palette. +; +; Input: +; AX = index of first color to read +; CX = number of colors +; ES:DI = pointer to destination buffer +; +ReadPalette PROC NEAR + mov dx, 03C7h + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop + ret +ReadPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxgc.asm b/16/xw/mxgc.asm new file mode 100755 index 00000000..85edf7a6 --- /dev/null +++ b/16/xw/mxgc.asm @@ -0,0 +1,54 @@ +;----------------------------------------------------------- +; +; MXGC.ASM - Get color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the selected DAC register. +; +; Input: +; Index = color index (0-255) +; R, G, B = byte pointers to red, green and blue +; Output: +; none +; +mxGetColor PROC FAR + ARG B:DWORD, \ + G:DWORD, \ + R:DWORD, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + + lds si, [R] + in al, dx + mov ds:[si], al + lds si, [G] + in al, dx + mov ds:[si], al + lds si, [B] + in al, dx + mov ds:[si], al + + .pop ds, si + .leave ARG_SIZE +mxGetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxgi.asm b/16/xw/mxgi.asm new file mode 100755 index 00000000..7037d411 --- /dev/null +++ b/16/xw/mxgi.asm @@ -0,0 +1,132 @@ +;----------------------------------------------------------- +; +; MXGI.ASM - Get image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGetImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies an image from screen to memory. +; +; Input: +; Image = pointer to buffer for image +; X, Y = coordinates of image on screen +; Width = width of image in pixels +; Height = height of image in pixels +; Output: +; none +; +mxGetImage PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + Count:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov si, bx + shr si, 1 + shr si, 1 + add si, ax + mov [PixelOffset], si + mov ds, [mx_VideoSegment] ; DS:SI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov di, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[di], bx + shr al, 1 + adc bx, 0 + dec di + dec di + jge @@PatchLoop + +; Get image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov es, WORD PTR Image[2] ; ES:DI will point to image + mov ah, [ReadPlane] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov di, WORD PTR Image[0] + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov si, [PixelOffset] ; DS:SI points to video memory +@@Loop: + .push si, di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move +@@MoveLoop: + movsb + add di, 3 + dec cx + jnz @@MoveLoop + .pop si, di + add di, [Width] ; Go to next image line + add si, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc ah + test ah, 04h ; Plane wraparound? + jz @@PlaneOk ; No + inc [PixelOffset] ; Yes, bump video pointer + and ah, 03h +@@PlaneOk: + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGetImage ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxgm.asm b/16/xw/mxgm.asm new file mode 100755 index 00000000..a67476a0 --- /dev/null +++ b/16/xw/mxgm.asm @@ -0,0 +1,63 @@ +;----------------------------------------------------------- +; +; MXGM.ASM - Gamma correction +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGammaCorrect + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +mx_tblGamma LABEL BYTE + DB 00, 10, 14, 17, 19, 21, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34 + DB 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46 + DB 47, 48, 48, 49, 49, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55 + DB 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63 + +;----------------------------------------------------------- +; +; Correct palette colors (gamma is 2.3). +; +; Input: +; CPal = pointer to color palette +; GPal = pointer to destination (gamma corrected) palette +; Count = number of colors to convert +; Output: +; none +; +; Note: CPal and GPal may point to the same buffer. +; +mxGammaCorrect PROC FAR + ARG Count:WORD, \ + DPal:DWORD, \ + SPal:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov cx, [Count] + jcxz @@Exit ; Exit now if nothing to do + lds si, [SPal] + les di, [DPal] + mov bx, OFFSET mx_tblGamma ; Setup BX for XLAT instruction + cld + mov ax, cx ; AX = Count + add cx, cx ; CX = Count*2 + add cx, ax ; CX = Count*3 +@@Loop: + lodsb + xlat mx_tblGamma + stosb + loop @@Loop + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxGammaCorrect ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxgp.asm b/16/xw/mxgp.asm new file mode 100755 index 00000000..6c143173 --- /dev/null +++ b/16/xw/mxgp.asm @@ -0,0 +1,56 @@ +;----------------------------------------------------------- +; +; MXGP.ASM - Get palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the current setting of the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to get +; Count = number of color to get +; Output: +; none +; +mxGetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push es, di + + les di, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C7h ; PEL read address register + out dx, al + inc dx + inc dx + cld +@@Loop: + in al, dx + stosb + in al, dx + stosb + in al, dx + stosb + loop @@Loop ; Loop until done + + .pop es, di + .leave ARG_SIZE +mxGetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxgv.asm b/16/xw/mxgv.asm new file mode 100755 index 00000000..2a54b1d0 --- /dev/null +++ b/16/xw/mxgv.asm @@ -0,0 +1,25 @@ +;----------------------------------------------------------- +; +; MXGV.ASM - Get version function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetVersion + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Returns the library version. +; +mxGetVersion PROC FAR + mov ax, MXVERSION + ret +mxGetVersion ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxhl.asm b/16/xw/mxhl.asm new file mode 100755 index 00000000..049a0566 --- /dev/null +++ b/16/xw/mxhl.asm @@ -0,0 +1,76 @@ +;----------------------------------------------------------- +; +; MXHL.ASM - Horizontal line mask utility +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC subHorizontalLineInfo + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +tblLeftSize DW 00h, 03h, 02h, 01h +tblLeftMask DB 00h, 0Eh, 0Ch, 08h +tblRightMask DB 00h, 01h, 03h, 07h +tblPatchMask DB 02h, 06h + +;----------------------------------------------------------- +; +; Prepares register for fast horizontal line drawing. +; +; Input: +; BX, AX = X, Y address of left pixel +; CX = line width +; Output: +; DI = left pixel offset in video memory +; AL = left block write plane mask (0 = none) +; AH = right block write plane mask (0 = none) +; CX = center block width in 4-pixel blocks +; +subHorizontalLineInfo PROC NEAR + ASSUME ds:NOTHING + + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax ; Offset of left pixel + + and bx, 03h + mov al, tblLeftMask[bx] + shl bx, 1 + sub cx, tblLeftSize[bx] + jge @@1 ; Ok to continue + +; Special case: start and end in the middle of a 4-pixel block. +; There are only three cases: +; Pixels Left mask CX CX+2 Patch mask Result +; 1) ..o. ..xx -1 1 .xx. ..x. +; 2) .oo. .xxx -1 1 .xx. .xx. +; 3) .o.. .xxx -2 0 .x.. .x.. +; All other cases are automatically handled with the standard masks. + mov bx, cx + inc bx + inc bx + and al, tblPatchMask[bx] ; Combine masks + xor ah, ah ; No right block + xor cx, cx ; No center block + jmp @@Exit + +@@1: + mov bx, cx + and bx, 03h + mov ah, tblRightMask[bx] + shr cx, 2 + +@@Exit: + ret +subHorizontalLineInfo ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxit.asm b/16/xw/mxit.asm new file mode 100755 index 00000000..c0d9cedd --- /dev/null +++ b/16/xw/mxit.asm @@ -0,0 +1,98 @@ +;----------------------------------------------------------- +; +; MXIT.ASM - Initialization/termination functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxInit +PUBLIC mxTerm + +PUBLIC mx_VideoSegment +PUBLIC mx_CodeSegment + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'MODEX library - Copyright (c) 1992-1994 Alessandro Scotti' + +mx_VideoSegment DW 0A000h +mx_CodeSegment DW SEG MX_TEXT + +;----------------------------------------------------------- +; +; Initialization. +; +; Input: +; none +; Output: +; AX = 0 on success +; +mxInit PROC FAR + LOCAL Result:WORD, \ + VideoSeg:WORD, \ + CStoDSalias:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov [Result], -1 ; Assume an error + mov [VideoSeg], 0A000h ; Real mode video segment + mov [CStoDSalias], cs ; Real mode data alias for CS + +; Check if running in protected mode under DPMI + mov ax, 1686h + int 2Fh + or ax, ax + jnz @@1 ; DPMI not found, continue in real mode + +; Get a data alias for CS + mov ax, 000Ah ; DMPI: create data alias + mov bx, cs + int 31h + jc @@Exit ; Exit if service failed + mov [CStoDSalias], ax ; Save data alias for CS +; Get a protected-mode selector for the video segment + mov ax, 0002h + mov bx, 0A000h ; Real mode segment of video + int 31h ; DPMI: get segment selector + jc @@Exit ; Exit if service failed + mov [VideoSeg], ax ; Save protected mode video selector + +; Initialize variables +@@1: + mov ds, [CStoDSalias] + ASSUME ds:MX_TEXT + mov [mx_CodeSegment], ds + mov ax, [VideoSeg] + mov [mx_VideoSegment], ax + +; Don't bother with VGA check for now... + + mov [Result], 0 + +@@Exit: + mov ax, [Result] + .pop ds, si, es, di + .leave +mxInit ENDP + +;----------------------------------------------------------- +; +; Termination. +; +; Input: +; none +; Output: +; always 0. +; +mxTerm PROC FAR + ASSUME ds:NOTHING + xor ax, ax + ret +mxTerm ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxll.asm b/16/xw/mxll.asm new file mode 100755 index 00000000..34fec043 --- /dev/null +++ b/16/xw/mxll.asm @@ -0,0 +1,82 @@ +;----------------------------------------------------------- +; +; MXLL.ASM - Load latches +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxLoadLatches + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD + +;----------------------------------------------------------- +; +; Loads the specified value into the VGA latches. +; +; Input: +; BL = value to load into latches +; Output: +; none +; Changes: +; bit mask register to FFh; +; function select register to "move"; +; write mode to 00h. +; Note: +; this is for internal use only. +; +mxLoadLatches PROC NEAR + ASSUME ds:NOTHING + + .push ds, si + mov dx, GDC + mov ax, 0FF08h + out dx, ax ; Set bit mask to FFh + mov ax, 0003h + out dx, ax ; Set function to "move" + mov ax, 0005h + out dx, ax ; Set write mode + mov ax, [mx_VideoSegment] + mov ds, ax + mov si, 0FFFFh + mov bh, 8 ; BH = write plane mask + mov cx, 3 ; CX = count = read plane +; Saves old values and force BL into latches +@@SetLoop: + mov dx, GDC + mov al, 04h + mov ah, cl + out dx, ax ; Select read plane + mov dx, TS + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + mov al, ds:[si] + push ax + mov ds:[si], bl + mov al, ds:[di] ; Force value into latch + shr bh, 1 ; Next write plane + loop @@SetLoop +; Restore previous values + mov cx, 3 + mov bh, 8 + mov dx, TS +@@ResetLoop: + mov al, 02h + mov ah, bh + out dx, ax ; Select write plane + pop ax + mov ds:[si], al + shr bh, 1 ; Next write plane + loop @@ResetLoop +; Exit + .pop ds, si + ret +mxLoadLatches ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxln.asm b/16/xw/mxln.asm new file mode 100755 index 00000000..fbc4ab94 --- /dev/null +++ b/16/xw/mxln.asm @@ -0,0 +1,414 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Line function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD + +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +tblDrawFunc LABEL WORD + DW subWidthMove + DW subHeightMove + DW subWidthOp + DW subHeightOp + +;----------------------------------------------------------- +; +; Draws a line from (X1,Y1) to (X2,Y2) using the Bresenham +; algorithm. +; +; Input: +; X1, Y1 = start point +; X2, Y2 = end point +; Color = line color +; Op = raster operator +; Output: +; none +; +; Note: the end point (X2,Y2) *IS* drawed. I don't like this very much +; but clipping is much simpler. +; +mxLine PROC FAR + ARG Op:WORD, \ + Color:WORD, \ + Y2:WORD, \ + X2:WORD, \ + Y1:WORD, \ + X1:WORD = ARG_SIZE + LOCAL Width:WORD, \ + Height:WORD, \ + ErrorAdd:WORD, \ + ErrorSub:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD, \ + P1:BYTE, \ + P2:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, di + ASSUME ds:NOTHING + + mov ax, [X1] + mov bx, [Y1] + mov cx, [X2] + mov dx, [Y2] + call subClipLine + jc @@Exit ; Line is full clipped + +; Get width + mov si, cx + xchg ax, si ; SI = X1, AX = X2 + sub ax, si + jge @@1 +; Swap points, we want X1 < X2 + xchg si, cx ; Swap X1 and X2 + xchg bx, dx ; Swap Y1 and Y2 + neg ax +@@1: + mov [Width], ax + +; Get height + mov cx, [mx_BytesPerLine] ; We don't need X2 anymore + mov ax, dx + sub ax, bx + jge @@2 + neg cx ; Move from bottom to top + neg ax ; Get absolute value of AX +@@2: + mov [Height], ax + mov [DeltaY], cx + +; Get pixel address and write plane + mov ax, bx + mul [mx_BytesPerLine] + mov cx, si ; CX = X1 + shr si, 1 + shr si, 1 + add si, ax ; SI = pixel offset + and cl, 03h + mov ax, 1102h + shl ah, cl + mov [WritePlane], ah + mov dx, TS + out dx, ax ; Set write plane + mov ax, [mx_VideoSegment] + mov ds, ax ; DS:SI points to (X1,Y1) + +; Select the function to handle the drawing loop + xor bx, bx + mov al, BYTE PTR [Op] + cmp al, OP_MOVE + je @@3 + and al, 03h + shl al, 1 + shl al, 1 + shl al, 1 + mov ah, al + mov al, 03h + mov dx, GDC + out dx, ax ; Set logical function + inc bx + inc bx +@@3: + mov ax, [Width] + mov cx, [Height] +; Horizontal, vertical and diagonal lines are not optimized yet + cmp ax, cx + jae @@4 + inc bx +@@4: + shl bx, 1 + call tblDrawFunc[bx] + +; Reset logical function if needed + cmp BYTE PTR [Op], OP_MOVE + je @@Exit + mov ax, 0003h + mov dx, GDC + out dx, ax + +@@Exit: + xor ax, ax + .pop ds, si, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Checks the coordinates of a line against the active +; clip region. +; Uses a variation of the Cohen-Sutherland algorithm developed +; by Victor Duvanenko. +; +; Input: +; AX, BX = X1, Y1 +; CX, DX = X2, Y2 +; Output: +; CF = set if line is full clipped +; AX, BX = clipped X1, Y1 +; CX, DX = clipped X2, Y2 +; Note: +; destroys SI, DI +; +subClipLine PROC NEAR + mov di, ax ; Copy X1 to DI and free AX + mov si, dx ; Copy Y2 to SI and free DX +; Compute clip codes for point (X2,Y2)=(CX,SI) + xor al, al +@@P2X1: cmp cx, [mx_ClipX1] + jge @@P2X2 + or al, 1 +@@P2X2: cmp cx, [mx_ClipX2] + jle @@P2Y1 + or al, 2 +@@P2Y1: cmp si, [mx_ClipY1] + jge @@P2Y2 + or al, 4 +@@P2Y2: cmp si, [mx_ClipY2] + jle @@P2XY + or al, 8 +@@P2XY: mov [P2], al +; Compute clip codes for point (X1,Y1)=(DI,BX) + xor al, al +@@P1X1: cmp di, [mx_ClipX1] + jge @@P1X2 + or al, 1 +@@P1X2: cmp di, [mx_ClipX2] + jle @@P1Y1 + or al, 2 +@@P1Y1: cmp bx, [mx_ClipY1] + jge @@P1Y2 + or al, 4 +@@P1Y2: cmp bx, [mx_ClipY2] + jle @@P1XY + or al, 8 +@@P1XY: mov [P1], al +; Check codes for trivial cases + mov ah, [P2] + test al, ah ; Is line invisible? + jnz @@FullClip ; Yes, exit + or ah, al ; Both points clipped? + jz @@Done ; Yes, exit +; Calculate deltas + mov ax, cx + sub ax, di + mov [DeltaX], ax + mov ax, si + sub ax, bx + mov [DeltaY], ax + mov al, [P1] ; Init clipping code +; Clipping loop +@@ClipLoop: + test al, al ; Is first point clipped? + jnz @@ClipX1 ; No, continue + xchg cx, di ; Swap points... + xchg bx, si + xchg al, [P2] ; ...and codes +; Clip left: Y1 = Y1 + DeltaY*(mx_ClipX1-X1)/DeltaX +@@ClipX1: + test al, 1 + jz @@ClipX2 + mov ax, [mx_ClipX1] + sub ax, di + mov di, [mx_ClipX1] + jmp @@ClipX1X2 +; Clip right: Y1 = Y1 + DeltaY*(mx_ClipX2-X1)/DeltaX +@@ClipX2: + test al, 2 + jz @@ClipY1 + mov ax, [mx_ClipX2] + sub ax, di + mov di, [mx_ClipX2] +@@ClipX1X2: + imul [DeltaY] + idiv [DeltaX] + add bx, ax + mov al, 8 + cmp bx, [mx_ClipY2] + jg @@CheckLoop + mov al, 4 + cmp bx, [mx_ClipY1] + jl @@CheckLoop + xor al, al + jmp @@CheckLoop +; Clip top: X1 = X1 + DeltaX*(mx_ClipY1-Y1)/DeltaY +@@ClipY1: + test al, 4 + jz @@ClipY2 + mov ax, [mx_ClipY1] + sub ax, bx + mov bx, [mx_ClipY1] + jmp @@ClipY1Y2 +; Clip bottom: X1 = X1 + DeltaX*(mx_ClipY2-Y1)/DeltaY +@@ClipY2: + mov ax, [mx_ClipY2] + sub ax, bx + mov bx, [mx_ClipY2] +@@ClipY1Y2: + imul [DeltaX] + idiv [DeltaY] + add di, ax + mov al, 1 + cmp di, [mx_ClipX1] + jl @@CheckLoop + mov al, 2 + cmp di, [mx_ClipX2] + jg @@CheckLoop + xor al, al +@@CheckLoop: + mov ah, [P2] + test al, ah + jnz @@FullClip + or ah, al + jnz @@ClipLoop + +@@Done: + mov ax, di + mov dx, si + clc + ret +@@FullClip: + stc + ret +subClipLine ENDP + +; Called when Width >= Height and Op = OP_MOVE +subWidthMove PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthMove ENDP + +; Called when Width < Height and Op = OP_MOVE +subHeightMove PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightMove ENDP + +; Called when Width >= Height and Op <> OP_MOVE +subWidthOp PROC NEAR + mov di, ax + neg di ; Initialize error term + shl cx, 1 + mov [ErrorAdd], cx + mov cx, ax + shl ax, 1 + mov [ErrorSub], ax + mov al, 02h + mov ah, [WritePlane] + mov bl, BYTE PTR [Color] + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] ; Latch data + mov ds:[si], bl + dec cx + jz @@Exit + rol ah, 1 + adc si, 0 + out dx, ax + add di, [ErrorAdd] + jl @@Loop + add si, [DeltaY] + sub di, [ErrorSub] + jmp @@Loop +@@Exit: + ret +subWidthOp ENDP + +; Called when Width < Height and Op <> OP_MOVE +subHeightOp PROC NEAR + mov di, cx + neg di ; Initialize error term + shl ax, 1 + mov [ErrorAdd], ax + mov ax, cx + shl ax, 1 + mov [ErrorSub], ax + mov bl, BYTE PTR [Color] + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + inc cx +@@Loop: + mov bh, ds:[si] + mov ds:[si], bl + dec cx + jz @@Exit + add si, [DeltaY] + add di, [ErrorAdd] + jl @@Loop + rol ah, 1 ; Next write plane + adc si, 0 ; Bump video offset if plane overflows + out dx, ax + sub di, [ErrorSub] ; Adjust error down + jmp @@Loop +@@Exit: + ret +subHeightOp ENDP + +mxLine ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxot.asm b/16/xw/mxot.asm new file mode 100755 index 00000000..62547665 --- /dev/null +++ b/16/xw/mxot.asm @@ -0,0 +1,330 @@ +;----------------------------------------------------------- +; +; MXOT.ASM - Text functions +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES ; We use the reserved name 'WIDTH' +INCLUDE MODEX.DEF + +PUBLIC mxOutChar +PUBLIC mxOutText +PUBLIC mxSetFont +PUBLIC mxSetTextColor +PUBLIC mxGetTextStep +PUBLIC mxSetTextStep + +MAX_WIDTH EQU 16 ; Must be <= 16 +MAX_HEIGHT EQU 32 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD +EXTRN mxPutImage : FAR + +; Default 8x8 font +fnt_Default LABEL + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW OP_MOVE ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +;----------------------------------------------------------- +; +; Sets the current font. +; +; Input: +; Font = pointer to font data +; Width = width of font character in pixels +; Height = height of font character in pixels +; Output: +; AX = 0 on success, else invalid parameters +; +; Note: when the high word of Font (i.e. the segment) is zero, the low +; word is used to select one of the system fonts. +; +mxSetFont PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Font:DWORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, WORD PTR Font[2] ; Get font segment + test ax, ax ; Null segment? + jnz @@UserFont ; No, install user font + +; Install system font + mov ax, WORD PTR Font[0] ; Get font number + cmp ax, MX_MAXSYSFONT ; Check range + jb @@SystemFont + xor ax, ax ; Out of range, use default font +@@SystemFont: + shl ax, 1 + shl ax, 1 + mov bx, ax + mov ax, tbl_SystemFont[bx] ; Get font offset + mov WORD PTR mx_FontPtr[0], ax + mov WORD PTR mx_FontPtr[2], cs + mov al, BYTE PTR tbl_SystemFont[bx+2] + xor ah, ah + mov [mx_FontWidth], ax + mov [mx_DeltaX], ax + mov dl, BYTE PTR tbl_SystemFont[bx+3] + xor dh, dh + mov [mx_FontHeight], dx + mul dx + mov [mx_FontCharSize], ax + mov [mx_DeltaX], ax + xor ax, ax + mov [mx_DeltaY], ax + jmp @@Exit + +; Install user font +@@UserFont: + mov ax, -1 ; Assume an error + mov bx, [Width] + cmp bx, MAX_WIDTH + ja @@Exit ; Invalid character width + mov dx, [Height] + cmp dx, MAX_HEIGHT + ja @@Exit ; Invalid character height + mov [mx_FontWidth], bx + mov [mx_FontHeight], dx + mov ax, bx + add ax, 7 + .shr ax, 3 + mul dx + mov [mx_FontCharSize], ax + mov ax, WORD PTR Font[0] + mov WORD PTR mx_FontPtr[0], ax + mov ax, WORD PTR Font[2] + mov WORD PTR mx_FontPtr[2], ax + xor ax, ax + +@@Exit: + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetFont ENDP + +;----------------------------------------------------------- +; +; Sets the text color and raster op. +; +; Input: +; Color = text color (foreground + background*256) +; Op = raster op +; Output: +; none +; +mxSetTextColor PROC FAR + ARG Op:WORD, \ + Color:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [Color] + mov [mx_FontColor], ax + mov ax, [Op] + mov [mx_FontOp], ax + + xor ax, ax + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetTextColor ENDP + +;----------------------------------------------------------- +; +; Writes a character using the current font and attributes. +; +; Input: +; X, Y = video coordinates +; C = character to print +; Output: +; none +; +mxOutChar PROC FAR + ARG C:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \ + Count:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Gets the pointer to font data for the selected character + lds si, DWORD PTR [mx_FontPtr] + mov al, [C] + xor ah, ah + mul [mx_FontCharSize] ; Offset into font + add si, ax ; DS:SI -> font data for character + +; Converts font data into a 256-color linear image + mov ax, ss + mov es, ax + lea di, [Image] + mov dx, [mx_FontColor] + mov ax, [mx_FontHeight] + mov [Count], ax +@@HeightLoop: + mov cx, [mx_FontWidth] + mov bh, ds:[si] + inc si ; Get a byte from font data + cmp cx, 8 + jbe @@WidthLoop ; Ok for width <= 8 + mov bl, ds:[si] ; Get another byte + inc si +@@WidthLoop: + mov al, dl ; Assume foreground color + shl bx, 1 ; Is font bit set? + jc @@1 ; Yes, foreground is just great + mov al, dh ; Get background color +@@1: + mov es:[di], al ; Put pixel into image + inc di + dec cx + jnz @@WidthLoop + dec [Count] + jnz @@HeightLoop + +; Now pass image to mx_PutImage + lea ax, [Image] + push es + push ax ; Pointer to image + push [X] + push [Y] ; Image coordinates + push [mx_FontWidth] + push [mx_FontHeight] ; Image size + push [mx_FontOp] ; Raster op + call mxPutImage ; Write character + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxOutChar ENDP + +;----------------------------------------------------------- +; +; Writes a string at the coordinates specified. +; +; Input: +; X, Y = text coordinates +; S = pointer to ASCIIZ string +; Output: +; none +; +mxOutText PROC FAR + ARG S:DWORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [S] +@@Loop: + mov al, ds:[si] + test al, al ; End of string? + jz @@Exit ; Yes, exit + inc si + push [X] ; Display character + push [Y] + push ax + call mxOutChar + mov ax, [mx_DeltaX] + add [X], ax ; Bump X coordinate + mov ax, [mx_DeltaY] + add [Y], ax ; Bump Y coordinate + dec [Count] + jnz @@Loop + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE + ret +mxOutText ENDP + +;----------------------------------------------------------- +; +; Sets the distance between characters. +; +; Input: +; DeltaX = horizontal distance in pixels +; DeltaY = vertical distance in pixels +; Output: +; none +; +; Note: this function may be used to set the text direction. +; +mxSetTextStep PROC FAR + ARG DeltaY:WORD, \ + DeltaX:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [DeltaX] + mov [mx_DeltaX], ax + mov ax, [DeltaY] + mov [mx_DeltaY], ax + + .pop ds + .leave ARG_SIZE +mxSetTextStep ENDP + +;----------------------------------------------------------- +; +; Gets the current distance between characters. +; +; Input: +; DeltaX = pointer to horizontal distance in pixels (integer) +; DeltaY = pointer to vertical distance in pixels (integer) +; Output: +; none +; +mxGetTextStep PROC FAR + ARG DeltaY:DWORD, \ + DeltaX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + mov ax, [mx_DeltaX] + lds si, [DeltaX] + mov ds:[si], ax + mov ax, [mx_DeltaY] + lds si, [DeltaY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetTextStep ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxpb.asm b/16/xw/mxpb.asm new file mode 100755 index 00000000..8c6aa449 --- /dev/null +++ b/16/xw/mxpb.asm @@ -0,0 +1,22 @@ +;----------------------------------------------------------- +; +; MXPB.ASM - Scan buffer for convex polygon fills +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mx_ScanBuffer + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +ALIGN 4 + +mx_ScanBuffer LABEL + DW POLYSCANBUFSIZE DUP(?) + +MX_TEXT ENDS +END diff --git a/16/xw/mxpf.asm b/16/xw/mxpf.asm new file mode 100755 index 00000000..db0da898 --- /dev/null +++ b/16/xw/mxpf.asm @@ -0,0 +1,420 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxFillPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + Y2 DW ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@Exit + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@Exit + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +@@Exit: + pop bp ; Restore BP + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxFillPoly PROC FAR + ARG Color:WORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc dx + inc di + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + .shl di, 2 ; Convert indexes to offsets + .shl si, 2 + lds bx, [Points] ; DS:BX -> point array + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 2 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + ja @@ClipYLoop ; Not clipped, continue +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov dx, TS + mov al, 02h + out dx, ax + mov ax, [Color] + mov dx, [mx_BytesPerLine] + shr cx, 1 + jnc @@FillScan + mov es:[di], al + add di, dx + jcxz @@DrawNext +@@FillScan: + mov es:[di], al + add di, dx + mov es:[di], al + add di, dx + dec cx + jnz @@FillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxFillPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxpg.asm b/16/xw/mxpg.asm new file mode 100755 index 00000000..caa7cf1b --- /dev/null +++ b/16/xw/mxpg.asm @@ -0,0 +1,589 @@ +;----------------------------------------------------------- +; +; MXPG.ASM - Convex polygon fill with Gouraud shading +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxGouraudPoly + +;----------------------------------------------------------- +; +; "Local" definitions +; +TPOINT STRUC + X DW ? + Y DW ? +TPOINT ENDS + +; Do NOT change order! +TSCAN STRUC + Y1 DW ? + E1 DB ? + C1 DB ? + Y2 DW ? + E2 DB ? + C2 DB ? +TSCAN ENDS + +MAXSCANCOLUMNS EQU POLYSCANBUFSIZE / SIZE TSCAN + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD +EXTRN mx_BytesPerLine : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD +EXTRN mx_ScanBuffer : NEAR + +;----------------------------------------------------------- +; +; Scans an edge using the DDA (digital differential analyzer) algorithm. +; Also interpolates color for shading. +; +; Input: +; DS:BX = pointer to start point (X1, Y1) +; DS:SI = pointer to end point (X2, Y2) +; ES:DI = pointer to edge buffer +; DX = start color +; AX = end color +; Output: +; ES:DI = updated pointer to edge buffer +; Notes: +; must preserve DS:SI. +; +subScan PROC NEAR + mov cx, ds:[si].X + sub cx, ds:[bx].X ; Get width + jg @@1 + ret +@@1: + push bp ; Save BP + push di ; Save scan info offset + push cx ; Save height + push ax ; Save colors + push dx + + mov ax, ds:[si].Y + mov bx, ds:[bx].Y + sub ax, bx ; Get height + jg @@T2B ; Scan top to bottom + jl @@B2T ; Scan bottom to top + +; Special case: vertical line + mov ax, bx +@@V: + mov es:[di].Y1, ax + add di, SIZE TSCAN + dec cx + jnz @@V + jmp @@GetColorInfo + +; Scan top to bottom +@@T2B: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@T2BLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@T2BLoop + jmp @@GetColorInfo + +; Scan bottom to top +@@B2T: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h +@@B2TLoop: + mov es:[di].Y1, ax + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@B2TLoop + +; Now get the color info +@@GetColorInfo: + pop bx ; Restore colors + pop ax + pop cx ; Height + pop di ; ES:DI -> scan info + + sub ax, bx ; Get color range + jg @@CL2R + jl @@CR2L + +; Special case: same color + mov ah, bl + mov al, 80h +@@CV: + mov WORD PTR es:[di].E1, ax + add di, SIZE TSCAN + dec cx + jnz @@CV + jmp @@Exit + +; Scan left to right +@@CL2R: + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx ; BP:BX = fixed 16:16 step + mov dx, 8000h +@@CL2RLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + add dx, bx + adc ax, bp + dec cx + jnz @@CL2RLoop + jmp @@Exit + +; Scan right to left +@@CR2L: + neg ax + cwd + div cx + mov bp, ax + xor ax, ax + div cx + xchg ax, bx + mov dx, 8000h + +@@CR2LLoop: + mov es:[di].C1, al + mov es:[di].E1, dh + add di, SIZE TSCAN + sub dx, bx + sbb ax, bp + dec cx + jnz @@CR2LLoop + +@@Exit: + pop bp + ret +subScan ENDP + +;----------------------------------------------------------- +; +; Fills a scan column. +; +; Input: +; DS:SI = current TSCAN +; ES:DI = address of top pixel +; CX = number of pixels to write +; DX = base color +; Output: +; none +; +subFillScan PROC NEAR + mov ax, WORD PTR ds:[si].E2 + mov bx, WORD PTR ds:[si].E1 + cmp ah, bh + jg @@L2R ; Color increases + jl @@R2L ; Color decreases + +; Special case: color doesn't change + add ax, dx + mov dx, [mx_BytesPerLine] +@@V: + mov es:[di], ah + add di, dx + dec cx + jnz @@V + ret + +; Color increases +@@L2R: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@L2RLoop: + mov es:[di], ah + add dx, bx + adc ax, bp + add di, si + dec cx + jnz @@L2RLoop + .pop bp, si + ret + +; Color decreases +@@R2L: + .push bp, si + mov si, bx + add si, dx ; Relocate color + sub ax, bx + neg ax + xor dx, dx + div cx + mov bp, ax ; BP = color step, integer part + xor ax, ax + div cx + mov bx, ax ; BX = color step, fractional part + mov dx, 8000h + mov ax, [mx_BytesPerLine] + xchg si, ax +@@R2LLoop: + mov es:[di], ah + sub dx, bx + sbb ax, bp + add di, si + dec cx + jnz @@R2LLoop + .pop bp, si + ret +subFillScan ENDP + +;----------------------------------------------------------- +; +; Fills a convex polygon with the specified color. +; Interpolates pixel colors using the Gouraud algorithm. +; +; Input: +; Count = number of vertexes +; Map = indexes of points and colors (integer) +; Points = array of points (integer X, Y coordinates) +; Colors = array of colors (integer) +; Color = base color +; Output: +; none +; Notes: +; vertexes must be in counterclockwise order, arrays are 0-based. +; +mxGouraudPoly PROC FAR + ARG Color:WORD, \ + Colors:DWORD, \ + Points:DWORD, \ + Map:DWORD, \ + Count:WORD = ARG_SIZE + LOCAL WritePlane:BYTE:2, \ + ScanOffsetT:WORD, \ + ScanOffsetB:WORD, \ + ScanCount:WORD, \ + Holder:WORD, \ + Height:WORD, \ + MinIdxT:WORD, \ + MinIdxB:WORD, \ + MaxIdx:WORD, \ + Width:WORD, \ + BoxX1:WORD, \ + BoxY1:WORD, \ + BoxX2:WORD, \ + BoxY2::WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Check that at least three vertexes are specified + mov cx, [Count] + cmp cx, 3 + jb @@Exit + +;------------------------------ +; Find bounding box for polygon + les di, [Map] + lds si, [Points] ; Pointer to vertex array + mov [BoxX1], 32767 + mov [BoxX2], -32768 + mov [BoxY1], 32767 + mov [BoxY2], -32768 + + xor dx, dx +@@MinMaxLoop: + mov bx, es:[di] ; Get index of vertex + .shl bx, 2 ; Get offset in point array + add bx, si + +; Check X range +@@CheckMinX: + mov ax, ds:[bx].X ; Get X coordinate + cmp ax, [BoxX1] + jge @@CheckMaxX + mov [BoxX1], ax + mov [MinIdxT], dx + mov [MinIdxB], dx +@@CheckMaxX: + cmp ax, [BoxX2] + jle @@CheckMinY + mov [BoxX2], ax + mov [MaxIdx], dx + +; Check Y range +@@CheckMinY: + mov ax, ds:[bx].Y + cmp ax, [BoxY1] + jge @@CheckMaxY + mov [BoxY1], ax +@@CheckMaxY: + cmp ax, [BoxY2] + jle @@CheckDone + mov [BoxY2], ax + +; Repeat thru all points +@@CheckDone: + inc di ; Next map entry + inc di + inc dx + inc dx + dec cx + jnz @@MinMaxLoop + +;--------------------------------- +; Check if polygon is full clipped + mov ax, [BoxX2] + cmp ax, [mx_ClipX1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxX1] + cmp bx, [mx_ClipX2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get width + jle @@Exit ; Exit if not positive + mov ax, [BoxY2] + cmp ax, [mx_ClipY1] ; Is poly full clipped? + jl @@Exit + mov bx, [BoxY1] + cmp bx, [mx_ClipY2] ; Is poly full clipped? + jg @@Exit + sub ax, bx ; Get height + jle @@Exit ; Exit if not positive + + dec [Count] + shl [Count], 1 ; We'll work with word offsets + mov es, [mx_CodeSegment] + +;-------------- +; Scan top edge + mov ax, OFFSET mx_ScanBuffer + mov [ScanOffsetT], ax + mov si, [MinIdxT] ; Offset of bottom point index +@@STLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of top point #1 + dec si ; Next point + dec si + test si, si + jnl @@ST1 + mov si, [Count] +@@ST1: + mov [MinIdxT], si ; Save new index of top point + mov si, ds:[bx+si] ; Get index of top point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetT] + call subScan ; Scan edge + mov [ScanOffsetT], di + mov si, [MinIdxT] + cmp si, [MaxIdx] ; End of edge? + jne @@STLoop ; No, continue + +;----------------- +; Scan bottom edge + mov ax, OFFSET mx_ScanBuffer + OFFSET Y2 + mov [ScanOffsetB], ax + mov si, [MinIdxB] ; Offset of bottom point index +@@SBLoop: + lds bx, [Map] ; DS:BX -> map table + mov di, ds:[bx+si] ; Index of bottom point #1 + inc si ; Next bottom point + inc si + cmp si, [Count] + jbe @@SB1 + xor si, si +@@SB1: + mov [MinIdxB], si ; Save new index of bottom point + mov si, ds:[bx+si] ; Get index of bottom point #2 + lds bx, [Colors] ; Get pointer to color array + shl di, 1 ; Convert indexes to offsets + shl si, 1 + mov ax, ds:[bx+si] ; Get colors + mov dx, ds:[bx+di] + lds bx, [Points] ; DS:BX -> point array + shl si, 1 + shl di, 1 + add si, bx ; DS:SI -> top point #2 + add bx, di ; DS:BX -> top point #1 + mov di, [ScanOffsetB] + call subScan ; Scan edge + mov [ScanOffsetB], di + mov si, [MinIdxB] + cmp si, [MaxIdx] ; End of edge? + jne @@SBLoop ; No, continue + +;-------------------- +; Clip left and right + mov si, OFFSET mx_ScanBuffer + mov ax, [BoxX1] + mov cx, [BoxX2] + sub cx, ax ; CX = bounding box width + mov bx, [mx_ClipX1] + sub bx, ax + jle @@ClipL1 ; No need to clip left + sub cx, bx ; Update width + add ax, bx ; BoxX1 = mx_ClipX1 + mov [BoxX1], ax + .shl bx, 3 ; Warning!!! This is an hand-coded + add si, bx ; multiply by the size of TSCAN +@@ClipL1: + mov bx, ax + add bx, cx ; Last scan column + sub bx, [mx_ClipX2] + jle @@ClipL2 ; No need to clip right + sub cx, bx ; Clip right +@@ClipL2: + test cx, cx ; Is clipped width positive? + jle @@Exit ; No, exit + mov [ScanCount], cx ; Save number of columns to draw + mov [ScanOffsetT], si ; Remember offset of (clipped) buffer + mov ds, [mx_CodeSegment] ; DS:SI -> scan buffer + +;------------------------------ +; Check if Y clipping is needed + mov ax, [BoxY1] + cmp ax, [mx_ClipY1] + jl @@ClipTB ; Need to clip top + mov ax, [BoxY2] + cmp ax, [mx_ClipY2] + jg @@ClipTB ; Need to clip bottom + jmp @@ClipYExit ; Skip Y clipping + +;-------------------- +; Clip top and bottom +@@ClipTB: + mov di, cx ; DI = scan count + inc di ; Increment count for pre-loop test + sub si, SIZE TSCAN +@@ClipYLoop: + dec di ; Any column left? + jz @@ClipYExit ; No, exit + add si, SIZE TSCAN + mov ax, ds:[si].Y1 ; Y1 + mov cx, ds:[si].Y2 ; Y2 + mov dx, [mx_ClipY2] + cmp ax, dx ; Full clipped? + jg @@ClipYClip ; Yes, skip this column + cmp cx, dx ; Need to clip bottom? + jle @@ClipY1 ; No, continue +; Clip bottom, need to scale colors too + mov ds:[si].Y2, dx + mov bx, cx + sub bx, dx ; Clip distance + sub cx, ax ; Height + jle @@ClipYClip + mov ax, WORD PTR ds:[si].E1 + sub ax, WORD PTR ds:[si].E2 + imul bx + idiv cx + add WORD PTR ds:[si].E2, ax + mov ax, ds:[si].Y1 ; Restore AX and CX + mov cx, ds:[si].Y2 +@@ClipY1: + mov dx, [mx_ClipY1] + cmp cx, dx ; Full top clipped? + jl @@ClipYClip ; Yes, skip + sub cx, ax ; Get height + jle @@ClipYClip ; Skip if not positive + cmp ax, dx ; Need to clip top? + jge @@ClipYLoop ; No, continue +; Clip top, need to scale colors too + mov ds:[si].Y1, dx ; Y1 = mx_ClipY1 + sub dx, ax ; DX = number of pixels clipped + cmp cx, dx + jbe @@ClipYClip ; Full clipped, skip + mov ax, WORD PTR ds:[si].E2 + sub ax, WORD PTR ds:[si].E1 ; AX = color distance + imul dx + idiv cx + add WORD PTR ds:[si].E1, ax ; Update starting color + jmp @@ClipYLoop +@@ClipYClip: + mov ds:[si].Y1, -1 ; Mark column as clipped + jmp @@ClipYLoop +@@ClipYExit: + +;------------- +; Draw columns + mov es, [mx_VideoSegment] + mov si, [ScanOffsetT] + mov cl, BYTE PTR [BoxX1] ; Init write plane + and cl, 03h + mov al, 11h + shl al, cl + mov [WritePlane], al + .shr [BoxX1], 2 + mov ax, [Color] ; Make 8:8 fixed color + mov ah, al + xor al, al + mov [Color], ax +@@DrawLoop: + mov ax, ds:[si].Y1 + test ax, ax ; Was column clipped? + js @@DrawNext ; Yes, skip + mov cx, ds:[si].Y2 + sub cx, ax ; CX = height + jle @@DrawNext + mul [mx_BytesPerLine] ; Get pixel address + add ax, [BoxX1] + mov di, ax + mov ah, [WritePlane] + mov al, 02h + mov dx, TS + out dx, ax + mov dx, [Color] + call subFillScan +@@DrawNext: + rol [WritePlane], 1 + adc [BoxX1], 0 ; Bump pointer to video memory if needed + add si, SIZE TSCAN + dec [ScanCount] + jnz @@DrawLoop + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxGouraudPoly ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxpi.asm b/16/xw/mxpi.asm new file mode 100755 index 00000000..9e8525f5 --- /dev/null +++ b/16/xw/mxpi.asm @@ -0,0 +1,267 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Put image +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutImage + +EXTRN subClipImage : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Move functions. +; Note: loops unrolled and optimized for CX even, no check for CX = 0. +; +subMove PROC NEAR + shr cx, 1 ; Make CX even + jc @@Odd ; Special case if odd byte +@@Loop: movsb + add si, 3 + movsb + add si, 3 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: movsb + add si, 3 + jcxz @@Exit + jmp @@Loop +subMove ENDP +; +subAnd PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + and es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + and es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subAnd ENDP +; +subOr PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + or es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + or es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subOr ENDP +; +subXor PROC NEAR + shr cx, 1 + jc @@Odd +@@Loop: mov al, ds:[si] + mov ah, ds:[si+4] + xor es:[di], ax + inc di + inc di + add si, 8 + dec cx + jnz @@Loop +@@Exit: ret +@@Odd: lodsb + xor es:[di], al + inc di + add si, 3 + jcxz @@Exit + jmp @@Loop +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: inc di + add si, 4 + dec cx + jnz @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + inc di + add si, 4 + dec cx + jnz @@Loop + ret +subAdd ENDP + +;----------------------------------------------------------- +; +; Copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxPutImage PROC FAR + ARG Op:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PlaneWidth:WORD:4, \ + PixelOffset:WORD, \ + MoveFunction:WORD, \ + Count:BYTE, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [Width] + mov dx, [Height] + call subClipImage + jc @@Exit ; Full clipped + mov [Height], dx + add WORD PTR Image[0], si ; Skip clipped pixels + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl + +; Compute extra bytes and width count for each plane + mov bx, cx + shr bx, 1 + shr bx, 1 ; Width for each plane + and cl, 03h + mov al, 00001000b + shr al, cl + mov si, 3 SHL 1 +@@PatchLoop: + mov PlaneWidth[si], bx + shr al, 1 + adc bx, 0 + dec si + dec si + jge @@PatchLoop + +; Setup planes for output to VGA registers + mov cl, [ReadPlane] + mov al, 00010001b + shl al, cl + mov [WritePlane], al + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + cld + mov [Count], 4 ; Four planes + lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane + mov ds, WORD PTR Image[2] +@@PlaneLoop: + cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do + je @@Exit ; (also, never try to move zero bytes!) + mov si, WORD PTR Image[0] + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov dx, [Height] + mov di, [PixelOffset] +@@Loop: + push si + push di + mov cx, WORD PTR ss:[bx] ; Number of bytes to move + mov ah, [OpInfo] ; Transparent color for subTrans + call [MoveFunction] + pop di + pop si + add si, [Width] ; Go to next image line + add di, [mx_BytesPerLine] ; Go to next screen row + dec dx + jnz @@Loop ; Repeat for all lines + inc bx + inc bx ; Select width for next plane + inc [ReadPlane] + rol [WritePlane], 1 + adc [PixelOffset], 0 + inc WORD PTR Image[0] + dec [Count] + jnz @@PlaneLoop ; Repeat for all planes + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutImage ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxpn.asm b/16/xw/mxpn.asm new file mode 100755 index 00000000..eaaf61b4 --- /dev/null +++ b/16/xw/mxpn.asm @@ -0,0 +1,60 @@ +;----------------------------------------------------------- +; +; MXPN.ASM - Panning function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxPan + +EXTRN mxWaitDisplay : FAR +EXTRN mxStartAddress : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Moves the screen. +; +; Input: +; X, Y = new X, Y coordinates of view screen +; Output: +; none +; +mxPan PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov ax, [Y] + mul [mx_BytesPerLine] + mov dx, [X] + shr dx, 1 + shr dx, 1 + add ax, dx + push ax ; Push the start address + call mxWaitDisplay + call mxStartAddress + + mov dx, 03DAh ; Set the pixel pan register + in al, dx + mov dx, 03C0h + mov al, 33h + out dx, al + mov al, BYTE PTR [X] + and al, 3 + shl al, 1 + out dx, al + + xor ax, ax + .leave ARG_SIZE +mxPan ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxpp.asm b/16/xw/mxpp.asm new file mode 100755 index 00000000..fc1755a3 --- /dev/null +++ b/16/xw/mxpp.asm @@ -0,0 +1,121 @@ +;----------------------------------------------------------- +; +; MXPP.ASM - Get/put pixel functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxGetPixel +PUBLIC mxPutPixel + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_VideoSegment : WORD +EXTRN mx_ClipX1 : WORD +EXTRN mx_ClipY1 : WORD +EXTRN mx_ClipX2 : WORD +EXTRN mx_ClipY2 : WORD + +;----------------------------------------------------------- +; +; Gets a pixel. +; +; Input: +; X, Y = pixel coordinates +; Output: +; pixel color +; +mxGetPixel PROC FAR + ARG Y:WORD, \ + X:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + xor ax, ax + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov bx, [Y] + cmp bx, [mx_ClipY1] + jl @@Exit + cmp bx, [mx_ClipY2] + jg @@Exit + + mov al, 04h ; Set read plane + mov ah, BYTE PTR [X] + and ah, 3 + mov dx, GDC + out dx, ax + + mov ds, [mx_VideoSegment] + mov ax, bx + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov al, ds:[si] ; Get pixel value + xor ah, ah + +@@Exit: + .pop ds, si + .leave ARG_SIZE +mxGetPixel ENDP + +;----------------------------------------------------------- +; +; Puts a pixel of the specified color. +; +; Input: +; X, Y = pixel coordinates +; Color = pixel color +; Output: +; none +; +mxPutPixel PROC FAR + ARG Color:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov si, [X] + cmp si, [mx_ClipX1] + jl @@Exit + cmp si, [mx_ClipX2] + jg @@Exit + mov ax, [Y] + cmp ax, [mx_ClipY1] + jl @@Exit + cmp ax, [mx_ClipY2] + jg @@Exit + + mov ds, [mx_VideoSegment] + mul [mx_BytesPerLine] + .shr si, 2 + add si, ax + + mov cl, BYTE PTR [X] ; Set write plane + and cl, 3 + mov ax, 0102h + shl ah, cl + mov dx, TS + out dx, ax + + mov al, [Color] ; Write pixel + mov ds:[si], al + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxPutPixel ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxra.asm b/16/xw/mxra.asm new file mode 100755 index 00000000..dd8e6839 --- /dev/null +++ b/16/xw/mxra.asm @@ -0,0 +1,37 @@ +;----------------------------------------------------------- +; +; MXRA.ASM - Row address +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRowAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the row address register. +; +; Input: +; RowAddress = row size in words +; Output: +; none +; +mxRowAddress PROC FAR + ARG RowAddress:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov dx, CRTC + mov al, 13h + mov ah, [RowAddress] + out dx, ax + xor ax, ax + .leave ARG_SIZE +mxRowAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxrp.asm b/16/xw/mxrp.asm new file mode 100755 index 00000000..de820c16 --- /dev/null +++ b/16/xw/mxrp.asm @@ -0,0 +1,101 @@ +;----------------------------------------------------------- +; +; MXRP.ASM - Rotate palette function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxRotatePalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Rotates the palette of the specified number of colors. +; +; Input: +; Palette = pointer to palette +; Count = number of colors to rotate +; Step = step size +; Output: +; none +; +; Note: if Step is positive palette is rotated left to right, otherwise +; right to left. +; +mxRotatePalette PROC FAR + ARG Step:WORD, \ + Count:WORD, \ + Palette:DWORD = ARG_SIZE + LOCAL Holder:BYTE:768 = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov bx, [Count] + add bx, bx + add bx, [Count] ; BX = Count*3 + + lds si, [Palette] ; DS:SI -> palette + push ss + pop es + lea di, Holder ; ES:DI -> local space + cld + + mov ax, [Step] + mov dx, ax + test ax, ax + jz @@Exit ; Nothing to do, exit + jl @@RightToLeft + +@@LeftToRight: + add ax, ax + add dx, ax ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + add si, bx + push si + mov cx, dx + rep movsb + mov es, WORD PTR Palette[2] + mov di, si + dec di ; ES:DI -> last byte of palette + pop si + dec si + mov cx, bx + std + rep movsb + push ss + pop ds + lea si, Holder + les di, [Palette] + mov cx, dx + cld + rep movsb + jmp @@Exit + +@@RightToLeft: + add ax, ax + add dx, ax + neg dx ; DX = Step*3 + sub bx, dx ; BX = (Count-Step)*3 + mov cx, dx + rep movsb + les di, [Palette] + mov cx, bx + rep movsb + push ss + pop ds + lea si, Holder + mov cx, dx + rep movsb + +@@Exit: + .pop ds, si, es, di + .leave ARG_SIZE +mxRotatePalette ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxsa.asm b/16/xw/mxsa.asm new file mode 100755 index 00000000..3ebae67d --- /dev/null +++ b/16/xw/mxsa.asm @@ -0,0 +1,44 @@ +;----------------------------------------------------------- +; +; MXSA.ASM - Start address function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxStartAddress + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Modifies the starting address of video memory. +; +; Input: +; StartAddr = new start address of video memory +; Output: +; none +; +mxStartAddress PROC FAR + ARG StartAddr:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + + mov bx, [StartAddr] + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + + .leave ARG_SIZE +mxStartAddress ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxsc.asm b/16/xw/mxsc.asm new file mode 100755 index 00000000..bcae45e6 --- /dev/null +++ b/16/xw/mxsc.asm @@ -0,0 +1,50 @@ +;----------------------------------------------------------- +; +; MXSC.ASM - Set color function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetColor + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the selected DAC register. +; +; Input: +; Index = index of color to set +; R, G, B = color components +; Output: +; none +; +mxSetColor PROC FAR + ARG B:BYTE:2, \ + G:BYTE:2, \ + R:BYTE:2, \ + Index:WORD = ARG_SIZE + .enter 0 + .push ds, si + + mov ax, [Index] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + + mov al, [R] + out dx, al + mov al, [G] + out dx, al + mov al, [B] + out dx, al + + .pop ds, si + .leave ARG_SIZE +mxSetColor ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxsi.asm b/16/xw/mxsi.asm new file mode 100755 index 00000000..b88d3b11 --- /dev/null +++ b/16/xw/mxsi.asm @@ -0,0 +1,317 @@ +;----------------------------------------------------------- +; +; MXPI.ASM - Stretch image +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStretchImage + +EXTRN subClipBox : NEAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +mxTable LABEL WORD ; Raster ops + DW subMove + DW subAnd + DW subOr + DW subXor + DW subTrans + DW subAdd + +;----------------------------------------------------------- +; +; Stretches and copies a "raw" image from memory to screen. +; +; Input: +; Image = pointer to image +; X, Y = coordinates of destination +; Width = width of image in pixels +; Height = height of image in pixels +; NewWidth = new width of image in pixels +; NewHeight = new height of image in pixels +; Op = raster op (OP_xxx) +; Output: +; none +; +mxStretchImage PROC FAR + ARG Op:WORD, \ + NewHeight:WORD, \ + NewWidth:WORD, \ + Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + LOCAL PixelOffset:WORD, \ + MoveFunction:WORD, \ + ReadPlane:BYTE, \ + OpInfo:BYTE, \ + WidthStep:DWORD, \ + HeightStep:DWORD, \ + ImageLo:WORD, \ + WritePlane:BYTE = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + +; Get width stretch factor + IF USE386 EQ TRUE + movzx edx, [Width] + xor eax, eax + movzx ebx, [NewWidth] + shl ebx, 16 + idiv ebx + mov [WidthStep], eax + ELSE + xor dx, dx ; Width stretch factor + mov ax, [Width] + mov bx, [NewWidth] + div bx + mov WORD PTR WidthStep[2], ax + xor ax, ax + div bx + mov WORD PTR WidthStep[0], ax + ENDIF +; Get height stretch factor + IF USE386 EQ TRUE + movzx edx, [Height] + xor eax, eax + movzx ebx, [NewHeight] + shl ebx, 16 + idiv ebx + mov [HeightStep], eax + ELSE + xor dx, dx + mov ax, [Height] + mov bx, [NewHeight] + div bx + mov WORD PTR HeightStep[2], ax + xor ax, ax + div bx + mov WORD PTR HeightStep[0], ax + ENDIF + +; Clip image + mov bx, [X] + mov ax, [Y] + mov cx, [NewWidth] + mov dx, [NewHeight] + call subClipBox + jc @@Exit ; Full clipped + mov [NewWidth], cx + mov [NewHeight], dx + sub [X], bx + sub [Y], ax + +; Get pixel address + mul [mx_BytesPerLine] + mov di, bx + shr di, 1 + shr di, 1 + add di, ax + mov [PixelOffset], di + mov es, [mx_VideoSegment] ; ES:DI points to pixel + and bl, 03h + mov [ReadPlane], bl ; Set read plane + mov cl, bl + mov al, 00010001b + shl al, cl + mov [WritePlane], al ; Set write plane + +; Relocate image origin if previously clipped + mov ax, [Y] + test ax, ax + jz @@OriginYDone + IF USE386 EQ TRUE + shl eax, 16 + imul [HeightStep] + mov ax, [Width] + mul dx + ELSE + mov bx, ax + mul WORD PTR HeightStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR HeightStep[2] + add ax, cx + mul [Width] + ENDIF + add WORD PTR [Image], ax +@@OriginYDone: + mov ax, [X] + test ax, ax + jz @@OriginXDone + IF USE386 EQ TRUE + shl eax, 16 + imul [WidthStep] + add WORD PTR [Image], dx + ELSE + mov bx, ax + mul WORD PTR WidthStep[0] + mov cx, dx + mov ax, bx + mul WORD PTR WidthStep[2] + add ax, cx + add WORD PTR [Image], ax + ENDIF +@@OriginXDone: + mov ax, WORD PTR HeightStep[2] + mul [Width] + mov WORD PTR HeightStep[2], ax + +; Install move function + mov bx, [Op] + mov [OpInfo], bh ; Remember additional info if needed + xor bh, bh + cmp bl, OP_ADD + jbe @@SetMoveFunction + xor bl, bl +@@SetMoveFunction: + shl bx, 1 + mov ax, mxTable[bx] + mov [MoveFunction], ax + +; Put image + mov ds, WORD PTR Image[2] + xor ax, ax + mov [ImageLo], ax +@@Loop: + mov si, WORD PTR Image[0] ; Get pointer to image + mov ah, [WritePlane] + and ah, 0Fh + mov al, 02h + mov dx, TS + out dx, ax ; Select write plane + mov ah, [ReadPlane] + and ah, 03h + mov al, 04h + mov dx, GDC + out dx, ax ; Select read plane + mov cx, [NewHeight] + mov di, [PixelOffset] ; ES:DI points to video memory + mov ah, [OpInfo] ; Additional raster op info + xor bx, bx + mov dx, [mx_BytesPerLine] + call [MoveFunction] ; Draw column + inc [ReadPlane] ; Next read plane + rol [WritePlane], 1 ; Next write plane + adc [PixelOffset], 0 ; Update video offset if needed + mov dx, WORD PTR WidthStep[0] + mov ax, WORD PTR WidthStep[2] + add [ImageLo], dx + adc WORD PTR Image[0], ax ; Next image column + dec [NewWidth] + jnz @@Loop ; Repeat for all columns + +@@Exit: + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE + +;----------------------------------------------------------- +; +; Move functions, on entry: +; AH = additional raster op info (e.g. transparent color) +; BX = 0, +; CX = pixel count, +; DX = mx_BytesPerLine. +; +subMove PROC NEAR +@@Loop: mov al, ds:[si] + mov es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subMove ENDP +; +subAnd PROC NEAR +@@Loop: mov al, ds:[si] + and es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAnd ENDP +; +subOr PROC NEAR +@@Loop: mov al, ds:[si] + or es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subOr ENDP +; +subXor PROC NEAR +@@Loop: mov al, ds:[si] + xor es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subXor ENDP +; +subTrans PROC NEAR +@@Loop: mov al, ds:[si] + cmp al, ah + je @@Skip + mov es:[di], al +@@Skip: + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subTrans ENDP +; +subAdd PROC NEAR +@@Loop: mov al, ds:[si] + add es:[di], al + add di, dx + dec cx + jz @@Exit + add si, WORD PTR HeightStep[2] + add bx, WORD PTR HeightStep[0] + jnc @@Loop + add si, [Width] + jmp @@Loop +@@Exit: ret +subAdd ENDP + +mxStretchImage ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxsl.asm b/16/xw/mxsl.asm new file mode 100755 index 00000000..d7908855 --- /dev/null +++ b/16/xw/mxsl.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXLN.ASM - Start line function +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxStartLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Changes the video start address to the specified line. +; +; Input: +; Line = new start line +; Output: +; none +; +mxStartLine PROC FAR + ARG Line:WORD = ARG_SIZE + .enter 0 + ASSUME ds:NOTHING + + mov ax, [Line] ; Get video offset + mul [mx_BytesPerLine] + xchg ax, bx ; Copy it into BX + +; Wait display + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + +; Set starting address + mov dx, CRTC + mov al, 0Ch ; Linear Starting Address high + mov ah, bh + cli + out dx, ax + mov al, 0Dh ; Linear Starting Address low + mov ah, bl + out dx, ax + sti + +; Wait retrace + mov dx, STATUS +@@2: in al,dx + test al, 08h + jz @@2 + + xor ax, ax + .leave ARG_SIZE +MX_TEXT ENDS +END diff --git a/16/xw/mxsm.asm b/16/xw/mxsm.asm new file mode 100755 index 00000000..183fba1e --- /dev/null +++ b/16/xw/mxsm.asm @@ -0,0 +1,508 @@ +;----------------------------------------------------------- +; +; MXSM.ASM - Set/change mode functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxChangeMode +PUBLIC mxGetAspect +PUBLIC mxGetScreenSize +PUBLIC mxSetMode + +PUBLIC mx_ScreenWidth +PUBLIC mx_ScreenHeight +PUBLIC mx_BytesPerLine + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mxSetSysClipRegion : FAR + +EXTRN mx_VideoSegment : WORD +EXTRN mx_CodeSegment : WORD + +mx_ScreenWidth DW ? ; Current screen width +mx_ScreenHeight DW ? +mx_AspectX DW ? ; Aspect ratio for current mode +mx_AspectY DW ? +mx_BytesPerLine DW 0 ; Bytes per line + +; +; Tables for setting video modes, sources: +; - MODEX.ASM, Matt Pritchard +; - Dr. Dobb's Journal, Michael Abrash +; - Fractint VIDEO.ASM module +; +TBL_SingleLine LABEL WORD ; CRTC + DW 04009h ; Cell height: 1 scan line + DW 00014h ; Double word mode off + DW 0E317h ; Byte mode on + DW 0 +TBL_DoubleLine LABEL WORD ; CRTC + DW 04109h ; Cell height: 2 scan lines + DW 00014h + DW 0E317h + DW 0 +TBL_Width320 LABEL WORD ; CRTC + DW 05F00h ; Horizontal total + DW 04F01h ; Horizontal displayed + DW 05002h ; Start horizontal blanking + DW 08203h ; End horizontal blanking + DW 05404h ; Start horizontal sync + DW 08005h ; End horizontal sync + DW 02813h ; Row address + DW 0 +TBL_Width360 LABEL WORD ; CRTC + DW 06B00h ; Horizontal total + DW 05901h ; Horizontal displayed + DW 05A02h ; Start horizontal blanking + DW 08E03h ; End horizontal blanking + DW 05E04h ; Start horizontal sync + DW 08A05h ; End horizontal sync + DW 02D13h ; Row address + DW 0 +TBL_Height175 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 08310h ; Start vertical sync + DW 08511h ; End vertical sync + DW 05D12h ; Vertical displayed + DW 06315h ; Start vertical blanking + DW 0BA16h ; End vertical blanking + DW 0 +TBL_Height200 LABEL WORD ; CRTC + DW 0BF06h ; Vertical total + DW 01F07h ; Overflow + DW 09C10h ; Start vertical sync + DW 08E11h ; End vertical sync + DW 08F12h ; Vertical displayed + DW 09615h ; Start vertical blanking + DW 0B916h ; End vertical blanking + DW 0 +TBL_Height240 LABEL WORD ; CRTC + DW 00D06h ; Vertical total + DW 03E07h ; Overflow + DW 0EA10h ; Start vertical sync + DW 08C11h ; End vertical sync + DW 0DF12h ; Vertical displayed + DW 0E715h ; Start vertical blanking + DW 00616h ; End vertical blanking + DW 0 +TBL_Tweak400x600: + DW 07400h + DW 06301h + DW 06402h + DW 09703h + DW 06804h + DW 09505h + DW 08606h + DW 0F007h + DW 06009h + DW 0310Fh + DW 05B10h + DW 08D11h + DW 05712h + DW 03213h + DW 00014h + DW 06015h + DW 08016h + DW 0E317h + DW 0 + +TBL_320x200: + DB 63h ; 400 scan lines, 25 MHz clock + DW 6, 5 ; Aspect: 6/5 = 1.2:1 + DW 320, 200 ; Size + DW TBL_Width320, TBL_Height200, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x240: + DB 0E3h ; 400 scan lines, 25 MHz clock + DW 1, 1 ; Aspect: 1/1 = 1:1 + DW 320, 240 ; Size + DW TBL_Width320, TBL_Height240, TBL_DoubleLine, 0 + DW 819 ; Max height +TBL_320x400: + DB 63h ; 480 scan lines, 25 MHz clock + DW 6, 10 ; Aspect: 6/10 = 0.6:1 + DW 320, 400 ; Size + DW TBL_Width320, TBL_Height200, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_320x480: + DB 0E3h ; 480 scan lines, 25 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 320, 480 ; Size + DW TBL_Width320, TBL_Height240, TBL_SingleLine, 0 + DW 819 ; Max height +TBL_360x200: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 20 ; Aspect: 27/20 = 1.35:1 + DW 360, 200 ; Size + DW TBL_Width360, TBL_Height200, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x240: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 8 ; Aspect: 9/8 = 1.125:1 + DW 360, 240 ; Size + DW TBL_Width360, TBL_Height240, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x400: + DB 067h ; 400 scan lines, 28 MHz clock + DW 27, 40 ; Aspect: 27/40 = 0.675:1 + DW 360, 400 ; Size + DW TBL_Width360, TBL_Height200, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_360x480: + DB 0E7h ; 480 scan lines, 28 MHz clock + DW 9, 16 ; Aspect: 9/16 = 0.5625:1 + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height240, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_320x175: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_DoubleLine, 0 + DW 819 +TBL_320x350: + DB 0A3h + DW 0, 0 ; Aspect: + DW 320, 175 + DW TBL_Width320, TBL_Height175, TBL_SingleLine, 0 + DW 819 +TBL_360x175: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_DoubleLine, 0 + DW 728 ; Max height +TBL_360x350: + DB 0A7h + DW 0, 0 ; Aspect: + DW 360, 480 ; Size + DW TBL_Width360, TBL_Height175, TBL_SingleLine, 0 + DW 728 ; Max height +TBL_400x600: + DB 0E7h ; 28 MHz clock + DW 1, 2 ; Aspect: 1/2 = 0.5:1 + DW 400, 600 ; Size + DW TBL_Tweak400x600, 0 + DW 655 ; Max height + +TBL_Mode LABEL WORD + DW TBL_320x175 + DW TBL_320x200 + DW TBL_320x240 + DW TBL_320x350 + DW TBL_320x400 + DW TBL_320x480 + DW TBL_360x175 + DW TBL_360x200 + DW TBL_360x240 + DW TBL_360x350 + DW TBL_360x400 + DW TBL_360x480 + DW TBL_400x600 + +MAXVMODE EQU ($-OFFSET TBL_Mode) / 2 + +;----------------------------------------------------------- +; +; Enables 80x25 color text mode +; +subText PROC NEAR + ASSUME ds:MX_TEXT + mov ax, 0003h + int 10h ; Call BIOS set mode + + mov [mx_ScreenHeight], 0 + mov [mx_BytesPerLine], 0 + ret +subText ENDP + +;----------------------------------------------------------- +; +; Enables the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; +mxSetMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jnz @@Set ; No, handle it + + call subText ; Back to text mode + jmp @@Exit ; Exit now + +; Set video mode +@@Set: + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + +; Use BIOS to set 320x200x256 linear mode + push si ; Save SI + mov ax, 0013h + int 10h ; Use BIOS to set 320x200 linear mode + pop si ; Restore SI + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + shr ax, 1 + shr ax, 1 ; Divide by four to get bytes per line + mov [mx_BytesPerLine], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Set virtual screen and system clip region + push [mx_ScreenWidth] + push WORD PTR ds:[bx] + call mxSetSysClipRegion + +; Clear video memory + mov dx, TS + mov ax, 0F02h + out dx, ax ; Enable all planes + mov es, [mx_VideoSegment] + xor di, di + mov cx, 8000h + xor ax, ax + rep stosw + +@@Done: +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxSetMode ENDP + +;----------------------------------------------------------- +; +; Changes from the current mode the selected graphics mode. +; +; Input: +; Mode = mode to select (MX_???x???) +; Output: +; none +; Notes: +; this function assumes that mxSetMode and mxSetVirtualScreen +; have been called first. View size is rearranged to match the +; specified mode, but video memory is not cleared. +; Differences from mxSetMode: +; - video BIOS is not called to initialize graphics; +; - row address register is not modified; +; - video memory is not cleared; +; - mx_BytesPerLine is not modified; +; - system clip region is not modified. +; +mxChangeMode PROC FAR + ARG Mode:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + +; Set DS to code segment alias + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov si, [Mode] + cmp si, MAXVMODE ; Is it a valid mode? + ja @@Exit ; No, exit + test si, si ; Text mode? + jz @@Exit ; Yes, exit + + dec si ; Skip text mode + shl si, 1 + mov si, TBL_Mode[si] + cld + + mov dx, TS + mov ax, 0604h + out dx, ax ; Disable chain-4 mode + mov ax, 0100h + out dx, ax ; Reset + mov dx, MISC + lodsb + out dx, al ; New timing/size + mov dx, TS + mov ax, 0300h + out dx, ax ; Restart sequencer + +; Unlock CRTC registers 0-7 + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + and al, 7Fh ; Clear write protect bit + out dx, al + + lodsw ; Get X aspect + mov [mx_AspectX], ax + lodsw ; Get Y aspect + mov [mx_AspectY], ax + lodsw ; Get screen width + mov [mx_ScreenWidth], ax + lodsw ; Get screen height + mov [mx_ScreenHeight], ax + +; Set CRTC registers + mov bx, si + mov dx, CRTC +@@TableLoop: + mov si, ds:[bx] ; DS:SI -> table of CRTC registers + inc bx + inc bx ; DS:BX -> offset of next table + test si, si ; Last table? + jz @@EndLoop ; Yes, exit loop +@@Loop: + lodsw ; Get CRTC register index and value + test ax, ax ; End of table? + jz @@TableLoop ; Yes, go to next table + cmp al, 13h ; Row address register? + je @@Loop ; Yes, ignore it + out dx, ax ; Set register AL to value AH + jmp @@Loop ; Get next register/value +@@EndLoop: + +; Lock CRTC registers 0-7 (some cards need this) + mov dx, CRTC + mov al, 11h + out dx, al ; Vertical sync end register + inc dx + in al, dx + or al, 80h ; Set write protect bit + out dx, al + +@@Exit: + xor ax, ax + mov ax, [mx_ScreenWidth] + .pop ds, si, es, di + .leave ARG_SIZE +mxChangeMode ENDP + +;----------------------------------------------------------- +; +; Returns the aspect ratio for the current mode. +; +; Input: +; AspectX = pointer to aspect X +; AspectY = pointer to aspect Y +; +; A rectangle of width AspectX and height AspectY looks like a square. +; +mxGetAspect PROC FAR + ARG AspectY:DWORD, \ + AspectX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [AspectX] + mov ax, [mx_AspectX] + mov ds:[si], ax + lds si, [AspectY] + mov ax, [mx_AspectY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetAspect ENDP + +;----------------------------------------------------------- +; +; Returns the current screen size. +; +; Input: +; Width = pointer to screen width +; Height = pointer to screen height +; +mxGetScreenSize PROC FAR + ARG SizeY:DWORD, \ + SizeX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [SizeX] + mov ax, [mx_ScreenWidth] + mov ds:[si], ax + lds si, [SizeY] + mov ax, [mx_ScreenHeight] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetScreenSize ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxsp.asm b/16/xw/mxsp.asm new file mode 100755 index 00000000..1d08e711 --- /dev/null +++ b/16/xw/mxsp.asm @@ -0,0 +1,57 @@ +;----------------------------------------------------------- +; +; MXSP.ASM - Set palette function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSetPalette + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Updates the VGA palette. +; +; Input: +; Buffer = pointer to palette data (R,G,B) +; Start = index of first color to set +; Count = number of color to set +; Output: +; none +; +mxSetPalette PROC FAR + ARG Count:WORD, \ + Start:WORD, \ + Buffer:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + lds si, [Buffer] + mov cx, [Count] + mov ax, [Start] + mov dx, 3C8h ; PEL write address register + out dx, al + inc dx + cld + cli ; Disable interrupts +@@Loop: + lodsb + out dx, al ; Red + lodsb + out dx, al ; Green + lodsb + out dx, al ; Blue + loop @@Loop ; Loop until done + sti ; Enable interrupts + + .pop ds, si + .leave ARG_SIZE +mxSetPalette ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxss.asm b/16/xw/mxss.asm new file mode 100755 index 00000000..97df7366 --- /dev/null +++ b/16/xw/mxss.asm @@ -0,0 +1,72 @@ +;----------------------------------------------------------- +; +; MXSS.ASM - Split screen function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxSplitScreen + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Splits the screen. +; +; Input: +; Line = scan line at which screen has to be splitted +; Output: +; none +; +mxSplitScreen PROC FAR + ARG Line:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + +; Modify the line compare value: bits 0-7 are in the Line Compare +; register (CRTC #18), bit 8 is in the Overflow Low register (CRTC #7) +; and bit 9 is in the Maximum Row Address register (CRTC #9) + mov ax, [Line] + shl ax, 1 ; Adjust line for mode "X" + mov bh, ah + mov bl, ah + and bx, 0201h + mov cl, 4 + shl bx, cl + shl bh, 1 + mov dx, CRTC +; Write bits 0-7 to line compare register + mov ah, al + mov al, 18h + out dx, ax +; Write bit 8 to overflow register + mov al, 07h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 11101111b + or ah, bl + mov al, 07h + out dx, ax +; Write bit 9 to maximum row address register + mov al, 09h + out dx, al + inc dx + in al, dx + dec dx + mov ah, al + and ah, 10111111b + or ah, bh + mov al, 09h + out dx, ax + + .leave ARG_SIZE +mxSplitScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxtl.asm b/16/xw/mxtl.asm new file mode 100755 index 00000000..69900c88 --- /dev/null +++ b/16/xw/mxtl.asm @@ -0,0 +1,169 @@ +;----------------------------------------------------------- +; +; MXTL.ASM - Put tile +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxPutTile +PUBLIC mxTransPutTile + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_VideoSegment : WORD +EXTRN mx_BytesPerLine : WORD + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + + shr cx, 1 ; Move line + rep movsw + rcl cx, 1 + rep movsb + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxPutTile ENDP + +;----------------------------------------------------------- +; +; Copies a "mode-x" tile from memory to screen. +; Skips over color 0. +; +; Input: +; Image = pointer to tile +; X, Y = coordinates of destination +; Width = width of image in pixels (Width and 3 = 0) +; Height = height of image in pixels +; Output: +; none +; Note: +; no clipping is performed on tiles! +; +mxTransPutTile PROC FAR + ARG Height:WORD, \ + Width:WORD, \ + Y:WORD, \ + X:WORD, \ + Image:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si, es, di + + mov ax, [Y] ; Get pixel address + mul [mx_BytesPerLine] + mov di, [X] + .shr di, 2 + add di, ax + mov es, [mx_VideoSegment] + + lds si, [Image] ; Get tile address + .shr [Width], 2 ; Number of bytes per plane + mov cl, BYTE PTR [X] + and cl, 3 + mov ah, 11h ; AH = plane mask + shl ah, cl ; Align mask to first plane + + mov [Y], 4 ; Number of planes + mov bx, [mx_BytesPerLine] + sub bx, [Width] ; Extra bytes per line +@@Loop: + mov al, 02h + mov dx, TS + out dx, ax ; Set write plane + mov [X], di ; Save video offset + mov dx, [Height] +@@Loop2: + mov cx, [Width] ; Number of bytes to move + +; Move one line + jcxz @@MoveLineDone +@@MoveLineLoop: + mov al, ds:[si] + test al, al + jz @@MoveLineNext + mov es:[di], al +@@MoveLineNext: + inc si + inc di + dec cx + jnz @@MoveLineLoop +@@MoveLineDone: + + add di, bx ; Move video offset to next line + dec dx ; Done all lines? + jnz @@Loop2 ; No, continue + mov di, [X] ; Restore video offset + rol ah, 1 ; Next plane + adc di, 0 ; Bump video offset if needed + dec [Y] ; Any plane left? + jnz @@Loop ; Yes, keep looping + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxTransPutTile ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxvs.asm b/16/xw/mxvs.asm new file mode 100755 index 00000000..992eabab --- /dev/null +++ b/16/xw/mxvs.asm @@ -0,0 +1,110 @@ +;----------------------------------------------------------- +; +; MXVS.ASM - Set/get virtual screen +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +NOWARN RES +INCLUDE MODEX.DEF + +PUBLIC mxSetVirtualScreen +PUBLIC mxGetVirtualScreen + +EXTRN mxRowAddress : FAR +EXTRN mxSetSysClipRegion : FAR + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_BytesPerLine : WORD +EXTRN mx_CodeSegment : WORD + +mx_VirtualWidth DW ? ; Virtual screen size +mx_VirtualHeight DW ? + +;----------------------------------------------------------- +; +; Sets the virtual screen. +; +; Input: +; Width = virtual screen width +; Height = virtual screen height +; Output: +; 0 on success, else invalid parameters +; +mxSetVirtualScreen PROC FAR + ARG Height:WORD, \ + Width:WORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds + +; Set DS to code segment + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, 1 ; Assume an error + cmp [Width], 320 ; Check width + jb @@Exit + push ax ; Save return code + mov dx, 0004h + xor ax, ax ; DX:AX = 256K + div [Width] ; Max height in AX + cmp [Height], ax + pop ax ; Restore return code + ja @@Exit ; Exit if bad heigth + + mov ax, [Width] + and ax, 0FFF8h ; Align to byte + mov [mx_VirtualWidth], ax + shr ax, 1 + shr ax, 1 + mov [mx_BytesPerLine], ax + shr ax, 1 + push ax + call mxRowAddress ; Set row address + mov ax, [Height] + mov [mx_VirtualHeight], ax + + push [Width] + push [Height] + call mxSetSysClipRegion + xor ax, ax + +@@Exit: + .pop ds + .leave ARG_SIZE +mxSetVirtualScreen ENDP + +;----------------------------------------------------------- +; +; Returns the current virtual screen size. +; +; Input: +; Width = pointer to virtual screen width +; Height = pointer to virtual screen height +; Output: +; none +; +mxGetVirtualScreen PROC FAR + ARG Height:DWORD, \ + Width:DWORD = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + .push ds, si + + mov ax, [mx_VirtualWidth] + lds si, [Width] + mov ds:[si], ax + mov ax, [mx_VirtualHeight] + lds si, [Height] + mov ds:[si], ax + + xor ax, ax + .pop ds, si + .leave ARG_SIZE +mxGetVirtualScreen ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxwd.asm b/16/xw/mxwd.asm new file mode 100755 index 00000000..de55208f --- /dev/null +++ b/16/xw/mxwd.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWD.ASM - Wait display function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitDisplay + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for display start. +; +mxWaitDisplay PROC FAR + mov dx, STATUS +@@1: in al, dx + test al, 08h + jnz @@1 + ret +mxWaitDisplay ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxwm.asm b/16/xw/mxwm.asm new file mode 100755 index 00000000..06158859 --- /dev/null +++ b/16/xw/mxwm.asm @@ -0,0 +1,39 @@ +;----------------------------------------------------------- +; +; MXWM.ASM - Set write mode function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWriteMode + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write mode. +; +; Input: +; Mode = write mode (0,1,2,3) +; Output: +; none +; +mxWriteMode PROC FAR + ARG Mode:BYTE:2 = ARG_SIZE + .enter 0 + + mov dx, GDC + mov ah, [Mode] + and ah, 00000011b + or ah, 01000000b + mov al, 05h + out dx, ax + + .leave ARG_SIZE +mxWriteMode ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxwp.asm b/16/xw/mxwp.asm new file mode 100755 index 00000000..19ca99d0 --- /dev/null +++ b/16/xw/mxwp.asm @@ -0,0 +1,62 @@ +;----------------------------------------------------------- +; +; MXWP.ASM - Set write/read plane functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWritePlane +PUBLIC mxReadPlane + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Sets the write plane(s). +; +; Input: +; Plane = write plane(s) to set (bit 0 enables plane 0, +; bit 1 enables plane 1 and so on, different planes +; may be selected at the same time) +; Output: +; none +; +mxWritePlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + .enter 0 + + mov ah, [Plane] + and ah, 00001111b ; Mask off unused bits + mov al, 02h + mov dx, TS + out dx, ax + + .leave ARG_SIZE +mxWritePlane ENDP + +;----------------------------------------------------------- +; +; Sets the read plane. +; +; Input: +; Plane = read plane to set (0,1,2,3) +; Output: +; none +; +mxReadPlane PROC FAR + ARG Plane:BYTE:2 = ARG_SIZE + ASSUME ds:NOTHING + .enter 0 + mov al, 04h + mov ah, [Plane] + and ah, 0000011b ; Mask off unused bits + mov dx, GDC + out dx, ax + .leave ARG_SIZE +mxReadPlane ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/mxwr.asm b/16/xw/mxwr.asm new file mode 100755 index 00000000..bd29fe59 --- /dev/null +++ b/16/xw/mxwr.asm @@ -0,0 +1,28 @@ +;----------------------------------------------------------- +; +; MXWR.ASM - Wait vertical retrace function +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxWaitRetrace + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +;----------------------------------------------------------- +; +; Waits for vertical retrace start. +; +mxWaitRetrace PROC FAR + mov dx, STATUS +@@1: in al,dx + test al, 08h + jz @@1 + ret +mxWaitRetrace ENDP + +MX_TEXT ENDS +END diff --git a/16/xw/readme.txt b/16/xw/readme.txt new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw/readme.txt @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw_/default.fnt b/16/xw_/default.fnt new file mode 100755 index 00000000..12eb22cb --- /dev/null +++ b/16/xw_/default.fnt @@ -0,0 +1,260 @@ +; +; MODEX library default font +; Copyright (c) 1993-1994 by Alessandro Scotti +; + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0 + DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1 + DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2 + DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3 + DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4 + DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5 + DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6 + DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7 + DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8 + DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9 + DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10 + DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11 + DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12 + DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13 + DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14 + DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15 + DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16 + DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17 + DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18 + DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19 + DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20 + DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21 + DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22 + DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23 + DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24 + DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25 + DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26 + DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27 + DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28 + DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29 + DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30 + DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; + DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; ! + DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; " + DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; # + DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $ + DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; % + DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; & + DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; ' + DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; ( + DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; ) + DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; * + DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; + + DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; , + DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; - + DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; . + DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; / + DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0 + DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1 + DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2 + DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3 + DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4 + DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5 + DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6 + DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7 + DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8 + DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9 + DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; : + DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ; + DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; < + DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; = + DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; > + DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ? + DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @ + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A + DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B + DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C + DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F + DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G + DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H + DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I + DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J + DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K + DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L + DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M + DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N + DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O + DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P + DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q + DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R + DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S + DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T + DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U + DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V + DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W + DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X + DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y + DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z + DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [ + DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \ + DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ] + DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^ + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _ + DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; ` + DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a + DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b + DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c + DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d + DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e + DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g + DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h + DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i + DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j + DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k + DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l + DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m + DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n + DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o + DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q + DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r + DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s + DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t + DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u + DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v + DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w + DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x + DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y + DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z + DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; { + DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; | + DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; } + DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~ + DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ;  + DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128 + DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129 + DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130 + DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131 + DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132 + DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133 + DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134 + DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135 + DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136 + DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137 + DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138 + DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139 + DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140 + DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141 + DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142 + DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143 + DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144 + DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145 + DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146 + DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147 + DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148 + DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149 + DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150 + DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151 + DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152 + DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153 + DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154 + DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155 + DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156 + DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157 + DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158 + DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159 + DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160 + DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161 + DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162 + DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163 + DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164 + DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165 + DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166 + DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167 + DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168 + DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169 + DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170 + DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171 + DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172 + DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173 + DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174 + DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175 + DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176 + DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177 + DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178 + DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179 + DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180 + DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181 + DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182 + DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183 + DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184 + DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185 + DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186 + DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187 + DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188 + DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189 + DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190 + DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191 + DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192 + DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193 + DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194 + DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195 + DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196 + DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197 + DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198 + DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199 + DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200 + DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201 + DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202 + DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203 + DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204 + DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205 + DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206 + DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207 + DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208 + DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209 + DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210 + DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211 + DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212 + DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213 + DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214 + DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215 + DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216 + DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217 + DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218 + DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219 + DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220 + DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221 + DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222 + DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223 + DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224 + DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225 + DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226 + DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227 + DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228 + DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229 + DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230 + DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231 + DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232 + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233 + DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234 + DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235 + DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236 + DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237 + DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238 + DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239 + DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240 + DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241 + DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242 + DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243 + DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244 + DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245 + DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246 + DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247 + DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248 + DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249 + DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250 + DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251 + DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252 + DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253 + DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255 diff --git a/16/xw_/makefile b/16/xw_/makefile new file mode 100755 index 00000000..cfe15232 --- /dev/null +++ b/16/xw_/makefile @@ -0,0 +1,132 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +!ifdef __LINUX__ +REMOVECOMMAND=rm -f +COPYCOMMAND=cp -f +DIRSEP=/ +OBJ=o +!else +REMOVECOMMAND=del +COPYCOMMAND=copy /y +DIRSEP=\ +OBJ=obj +!endif +LIBINCS = modex.def + +LIBOBJS = mxbb.$(OBJ) mxcc.$(OBJ) mxcg.$(OBJ) mxcl.$(OBJ) mxcr.$(OBJ) mxfb.$(OBJ) mxgc.$(OBJ) mxgi.$(OBJ) mxgm.$(OBJ) mxgp.$(OBJ) mxgv.$(OBJ) mxhl.$(OBJ) mxit.$(OBJ) mxll.$(OBJ) mxln.$(OBJ) mxot.$(OBJ) mxpb.$(OBJ) mxpf.$(OBJ) mxpg.$(OBJ) mxpi.$(OBJ) mxpn.$(OBJ) mxpp.$(OBJ) mxra.$(OBJ) mxrp.$(OBJ) mxsa.$(OBJ) mxsc.$(OBJ) mxsi.$(OBJ) mxsl.$(OBJ) mxsm.$(OBJ) mxsp.$(OBJ) mxss.$(OBJ) mxtl.$(OBJ) mxvs.$(OBJ) mxwd.$(OBJ) mxwm.$(OBJ) mxwp.$(OBJ) mxwr.$(OBJ) +#mxfp.$(OBJ) +# +# ASM compiler +# +ASMC =wasm +ASMO =-mh -0 + +# +# PAS compiler +# +#PASC = tpc +#PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = wlib + +# .asm.obj: +# $(ASMC) $(ASMO) $< + +mxbb.$(OBJ): mxbb.asm + $(ASMC) $(ASMO) mxbb.asm +mxcc.$(OBJ): mxcc.asm + $(ASMC) $(ASMO) mxcc.asm +mxcg.$(OBJ): mxcg.asm + $(ASMC) $(ASMO) mxcg.asm +mxcl.$(OBJ): mxcl.asm + $(ASMC) $(ASMO) mxcl.asm +mxcr.$(OBJ): mxcr.asm + $(ASMC) $(ASMO) mxcr.asm +mxfb.$(OBJ): mxfb.asm + $(ASMC) $(ASMO) mxfb.asm +mxfp.$(OBJ): mxfp.asm + $(ASMC) $(ASMO) mxfp.asm +mxgc.$(OBJ): mxgc.asm + $(ASMC) $(ASMO) mxgc.asm +mxgi.$(OBJ): mxgi.asm + $(ASMC) $(ASMO) mxgi.asm +mxgm.$(OBJ): mxgm.asm + $(ASMC) $(ASMO) mxgm.asm +mxgp.$(OBJ): mxgp.asm + $(ASMC) $(ASMO) mxgp.asm +mxgv.$(OBJ): mxgv.asm + $(ASMC) $(ASMO) mxgv.asm +mxhl.$(OBJ): mxhl.asm + $(ASMC) $(ASMO) mxhl.asm +mxit.$(OBJ): mxit.asm + $(ASMC) $(ASMO) mxit.asm +mxll.$(OBJ): mxll.asm + $(ASMC) $(ASMO) mxll.asm +mxln.$(OBJ): mxln.asm + $(ASMC) $(ASMO) mxln.asm +mxot.$(OBJ): mxot.asm + $(ASMC) $(ASMO) mxot.asm +mxpb.$(OBJ): mxpb.asm + $(ASMC) $(ASMO) mxpb.asm +mxpf.$(OBJ): mxpf.asm + $(ASMC) $(ASMO) mxpf.asm +mxpg.$(OBJ): mxpg.asm + $(ASMC) $(ASMO) mxpg.asm +mxpi.$(OBJ): mxpi.asm + $(ASMC) $(ASMO) mxpi.asm +mxpn.$(OBJ): mxpn.asm + $(ASMC) $(ASMO) mxpn.asm +mxpp.$(OBJ): mxpp.asm + $(ASMC) $(ASMO) mxpp.asm +mxra.$(OBJ): mxra.asm + $(ASMC) $(ASMO) mxra.asm +mxrp.$(OBJ): mxrp.asm + $(ASMC) $(ASMO) mxrp.asm +mxsa.$(OBJ): mxsa.asm + $(ASMC) $(ASMO) mxsa.asm +mxsc.$(OBJ): mxsc.asm + $(ASMC) $(ASMO) mxsc.asm +mxsi.$(OBJ): mxsi.asm + $(ASMC) $(ASMO) mxsi.asm +mxsl.$(OBJ): mxsl.asm + $(ASMC) $(ASMO) mxsl.asm +mxsm.$(OBJ): mxsm.asm + $(ASMC) $(ASMO) mxsm.asm +mxsp.$(OBJ): mxsp.asm + $(ASMC) $(ASMO) mxsp.asm +mxss.$(OBJ): mxss.asm + $(ASMC) $(ASMO) mxss.asm +mxtl.$(OBJ): mxtl.asm + $(ASMC) $(ASMO) mxtl.asm +mxvs.$(OBJ): mxvs.asm + $(ASMC) $(ASMO) mxvs.asm +mxwd.$(OBJ): mxwd.asm + $(ASMC) $(ASMO) mxwd.asm +mxwm.$(OBJ): mxwm.asm + $(ASMC) $(ASMO) mxwm.asm +mxwp.$(OBJ): mxwp.asm + $(ASMC) $(ASMO) mxwp.asm +mxwr.$(OBJ): mxwr.asm + $(ASMC) $(ASMO) mxwr.asm + +all: $(LIBOBJS) modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw_/makefile.bcc b/16/xw_/makefile.bcc new file mode 100755 index 00000000..d3ad8b71 --- /dev/null +++ b/16/xw_/makefile.bcc @@ -0,0 +1,81 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +LIBINCS = MODEX.DEF + +LIBOBJS = MXBB.OBJ \ + MXCC.OBJ \ + MXCG.OBJ \ + MXCL.OBJ \ + MXCR.OBJ \ + MXFB.OBJ \ + MXFP.OBJ \ + MXGC.OBJ \ + MXGI.OBJ \ + MXGM.OBJ \ + MXGP.OBJ \ + MXGV.OBJ \ + MXHL.OBJ \ + MXIT.OBJ \ + MXLL.OBJ \ + MXLN.OBJ \ + MXOT.OBJ \ + MXPB.OBJ \ + MXPF.OBJ \ + MXPG.OBJ \ + MXPI.OBJ \ + MXPN.OBJ \ + MXPP.OBJ \ + MXRA.OBJ \ + MXRP.OBJ \ + MXSA.OBJ \ + MXSC.OBJ \ + MXSI.OBJ \ + MXSL.OBJ \ + MXSM.OBJ \ + MXSP.OBJ \ + MXSS.OBJ \ + MXTL.OBJ \ + MXVS.OBJ \ + MXWD.OBJ \ + MXWM.OBJ \ + MXWP.OBJ \ + MXWR.OBJ + +# +# ASM compiler +# +ASMC = tasm +ASMO = /m5 /p + +# +# PAS compiler +# +PASC = tpc +PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = tlib + +.asm.obj: + $(ASMC) $(ASMO) $< + +target: modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw_/modex.bak b/16/xw_/modex.bak new file mode 100755 index 00000000..560a1c68 Binary files /dev/null and b/16/xw_/modex.bak differ diff --git a/16/xw_/modex.def b/16/xw_/modex.def new file mode 100755 index 00000000..7977a4a0 --- /dev/null +++ b/16/xw_/modex.def @@ -0,0 +1,163 @@ +;------------------------------------------------------------ +; +; MODEX.DEF - Include file +; Copyright (c) 1993-1994 by Alessandro Scotti +; +;JUMPS +;LOCALS + +TRUE EQU 1 ; Boolean constants +FALSE EQU 0 + +USE286 = FALSE ; TRUE enables 80286 instructions +USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions + +IF USE286 EQ TRUE + P286 +ENDIF + +IF USE386 EQ TRUE + P386 + USE286 = TRUE +ENDIF + +MXVERSION EQU 0128h ; Library version (1.40) + +;------------------------------------------------------------ +; +; VGA definitions +; +MISC EQU 3C2h ; Miscellaneous output +TS EQU 3C4h ; Timing Sequencer index register +GDC EQU 3CEh ; Graphics Data Controller index register +CRTC EQU 3D4h ; CRTC index register +STATUS EQU 3DAh ; Input Status register one + +;------------------------------------------------------------ +; +; Raster operators +; +OP_SET EQU 0 +OP_MOVE EQU 0 ; Same as OP_SET +OP_AND EQU 1 +OP_OR EQU 2 +OP_XOR EQU 3 +OP_TRANS EQU 4 +OP_ADD EQU 5 ; Must be last op + +;------------------------------------------------------------ +; +; Polygon fill functions +; +POLYSCANBUFSIZE EQU 4*1024 + +;------------------------------------------------------------ +; Macro to push registers, variables or flags onto the stack +; Usage: .push "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.PUSH has more than 10 arguments> + ENDIF + IRP $reg, + IFB <$reg> ;; Is argument blank? + EXITM ;; Yes, exit + ELSEIFIDNI <$reg>, ;; Is argument the keyword "FLAGS"? + pushf ;; Yes, push flags + ELSE + push $reg ;; Push argument + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; Macro to pop registers, variables or flags from the stack +; Usage: .pop "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.POP has more than 10 arguments> + ENDIF + IRP $reg, + IFNB <$reg> ;; Is argument non-blank? + IFIDNI <$reg>, ;; Yes, is it the keyword "FLAGS"? + popf ;; Yes, pop flags + ELSE + pop $reg ;; Pop argument + ENDIF + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; +.enter MACRO localsize + IF USE286 EQ TRUE + enter localsize, 0 + ELSE + push bp + mov bp, sp + sub sp, localsize + ENDIF +ENDM + +;------------------------------------------------------------ +; +;.leave MACRO argsize +; IF USE286 EQ TRUE +; leave +; ELSE +; mov sp, bp +; pop bp +; ENDIF +; IFNB +; ret argsize +; ELSE +; ret +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shr MACRO arg, count +; IF USE286 EQ TRUE +; shr arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shr arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shl MACRO arg, count +; IF USE286 EQ TRUE +; shl arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shl arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.chk386 MACRO name, jump +; IF USE386 EQ FALSE +; .OUT "Warning: ", , " needs a 386 or better to run!" +; jmp @@jump +; ENDIF +;ENDM diff --git a/16/xw_/modex.h b/16/xw_/modex.h new file mode 100755 index 00000000..2c1f1ebe --- /dev/null +++ b/16/xw_/modex.h @@ -0,0 +1,153 @@ +/* + MODEX.H - C/C++ include file for the MODEX library + Copyright (c) 1994 Alessandro Scotti +*/ + +#ifndef _MODEX_H_ // Avoid nested inclusions +#define _MODEX_H_ + +// +// Video modes +// +#define MX_TEXT 0 // 80x25 text +#define MX_320x175 1 // 320x175x256 +#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5 +#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1 +#define MX_320x350 4 // 320x350x256 +#define MX_320x400 5 // 320x400x256, 2 pages +#define MX_320x480 6 // 320x480x256, 1 page +#define MX_360x175 7 // 360x175x256 +#define MX_360x200 8 // 360x200x256, 3 pages +#define MX_360x240 9 // 360x240x256, 2 pages +#define MX_360x350 10 // 360x350x256 +#define MX_360x400 11 // 360x400x256, 1 page +#define MX_360x480 12 // 360x480x256, 1 page +#define MX_400x600 13 // 400x600x256, 1 page + +// +// Fade effects +// +#define MX_FADEIN 0 +#define MX_FADEOUT 1 + +// +// Raster ops +// +#define OP_SET 0 // No operator +#define OP_AND 1 // And +#define OP_OR 2 // Or +#define OP_XOR 3 // Xor +#define OP_TRANS 4 // Transparent +#define OP_ADD 5 // Additive +#define OP_MOVE 0 // Alias for OP_SET + +// +// Temporary definitions +// +#define MXBYTE unsigned char +#define MXBOOL short int +#define MXSINT short int +#define MXUINT unsigned short int +#define MXAPI far pascal +#define MXPTR void far * + +// Functions + +#ifdef __cplusplus // Avoid C++ name mangling +extern "C" { +#endif + +// +// Initialization +// +MXSINT MXAPI mxInit( void ); // Returns 0 if successful +void MXAPI mxTerm( void ); +MXUINT MXAPI mxGetVersion( void ); +// +// Mode setting +// +void MXAPI mxChangeMode( MXUINT mode ); +void MXAPI mxSetMode( MXUINT mode ); +void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty ); +void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height ); +// +// Hardware support +// +void MXAPI mxWriteMode( MXBYTE wm ); +void MXAPI mxSplitScreen( MXUINT line ); +void MXAPI mxStartAddress( MXUINT sa ); +void MXAPI mxStartLine( MXUINT sl ); +void MXAPI mxWaitDisplay( void ); +void MXAPI mxWaitRetrace( void ); +void MXAPI mxWritePlane( MXBYTE wp ); +void MXAPI mxReadPlane( MXBYTE rp ); +void MXAPI mxRowAddress( MXBYTE ra ); +// +// Virtual screen +// +void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height ); +void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height ); +void MXAPI mxPan( MXUINT x, MXUINT y ); +// +// Clipping +// +MXBOOL MXAPI mxGetClip( void ); +MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h ); +MXBOOL MXAPI mxSetClip( MXBOOL ); +void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height ); +// +// Graphics +// +void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy ); +void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op ); +MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y ); +void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color ); +void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op ); +void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op ); +void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h ); +void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color ); +void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op ); +// +// Palette +// +void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b ); +void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue ); +void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT ); +void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step ); +// +// Text +// +MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight ); +void MXAPI mxSetTextColor( MXUINT color, MXUINT op ); +void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay ); +void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay ); +void MXAPI mxOutChar( MXSINT x, MXSINT y, char c ); +void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz ); +// +// Convex polygons +// +void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); + +#ifdef __cplusplus +} +#endif + +// +// Remove temporary defines +// +#undef MXBYTE +#undef MXBOOL +#undef MXSINT +#undef MXUINT +#undef MXPTR +#undef MXAPI + +#endif // _MODEX_H_ diff --git a/16/xw_/modex.lbr b/16/xw_/modex.lbr new file mode 100755 index 00000000..93fc7801 --- /dev/null +++ b/16/xw_/modex.lbr @@ -0,0 +1,39 @@ ++-MXBB.OBJ & ++-MXCC.OBJ & ++-MXCG.OBJ & ++-MXCL.OBJ & ++-MXCR.OBJ & ++-MXFB.OBJ & ++-MXFP.OBJ & ++-MXGC.OBJ & ++-MXGI.OBJ & ++-MXGM.OBJ & ++-MXGP.OBJ & ++-MXGV.OBJ & ++-MXHL.OBJ & ++-MXIT.OBJ & ++-MXLL.OBJ & ++-MXLN.OBJ & ++-MXOT.OBJ & ++-MXPB.OBJ & ++-MXPF.OBJ & ++-MXPG.OBJ & ++-MXPI.OBJ & ++-MXPN.OBJ & ++-MXPP.OBJ & ++-MXPT.OBJ & ++-MXRA.OBJ & ++-MXRP.OBJ & ++-MXSA.OBJ & ++-MXSC.OBJ & ++-MXSI.OBJ & ++-MXSL.OBJ & ++-MXSM.OBJ & ++-MXSP.OBJ & ++-MXSS.OBJ & ++-MXTL.OBJ & ++-MXVS.OBJ & ++-MXWD.OBJ & ++-MXWM.OBJ & ++-MXWP.OBJ & ++-MXWR.OBJ diff --git a/16/xw_/modex.pas b/16/xw_/modex.pas new file mode 100755 index 00000000..7d9d26ed --- /dev/null +++ b/16/xw_/modex.pas @@ -0,0 +1,194 @@ +(* + Turbo Pascal interface to the MODEX library + Copyright (c) 1993,1994 by Alessandro Scotti +*) +unit ModeX; +interface + +const + (* Video modes *) + MX_TEXT = 0; + MX_320x175 = 1; + MX_320x200 = 2; + MX_320x240 = 3; + MX_320x350 = 4; + MX_320x400 = 5; + MX_320x480 = 6; + MX_360x175 = 7; + MX_360x200 = 8; + MX_360x240 = 9; + MX_360x350 = 10; + MX_360x400 = 11; + MX_360x480 = 12; + MX_400x600 = 13; + + (* Fade effects *) + MX_FADEIN = 0; + MX_FADEOUT = 1; + + (* Raster ops *) + OP_SET = 0; + OP_AND = 1; + OP_OR = 2; + OP_XOR = 3; + OP_TRANS = 4; + OP_ADD = 5; + OP_MOVE = 0; (* Alias for OP_SET *) + +procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer ); +procedure mxCircle( CX, CY: integer; Radius: word; Color: byte ); +procedure mxChangeMode( Mode: word ); +procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word ); +procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word ); +procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word ); +procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word ); +procedure mxGetAspect( var AspectX, AspectY: word ); +function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean; +function mxGetClip: boolean; +procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word ); +procedure mxGetPalette( Palette: pointer; Start, Count: word ); +function mxGetPixel( X, Y: word ): byte; +procedure mxGetScreenSize( var Width, Height: word ); +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); +function mxGetVersion: word; +procedure mxGetVirtualScreen( var Width, Height: word ); +procedure mxInit; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); +procedure mxOutChar( X, Y: integer; C: char ); +procedure mxOutText( X, Y: integer; S: pointer ); +procedure mxPan( X, Y: word ); +procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word ); +procedure mxPutPixel( X, Y: word; C: byte ); +procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxReadPlane( Plane: byte ); +procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer ); +procedure mxRowAddress( RowAddress: byte ); +function mxSetClip( Clip: boolean ): boolean; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); +procedure mxSetColor( Index, R, G, B: word ); +procedure mxSetFont( Font: pointer; Width, Height: word ); +procedure mxSetMode( Mode: word ); +procedure mxSetPalette( Palette: pointer; Start, Count: word ); +procedure mxSetTextColor( Color, Op: word ); +procedure mxSetTextStep( DeltaX, DeltaY: integer ); +procedure mxSetVirtualScreen( Width, Height: word ); +procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word ); +procedure mxSplitScreen( Line: word ); +procedure mxStartAddress( StartAddress: word ); +procedure mxStartLine( Line: word ); +procedure mxTerm; +procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxWaitDisplay; +procedure mxWaitRetrace; +procedure mxWriteMode( Mode: byte ); +procedure mxWritePlane( Plane: byte ); + +procedure mxFillPoly( Count: word; var Map, Points; Color: word ); +procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word ); +procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word ); + +procedure mxOutStr( X, Y: integer; S: string ); + +implementation + +procedure mxBitBlt; external; +procedure mxChangeMode( Mode: word ); external; +procedure mxCircle; external; +procedure mxColorToGray; external; +procedure mxFadePalette; external; +procedure mxFillBox; external; +procedure mxGammaCorrect; external; +procedure mxGetAspect( var AspectX, AspectY: word ); external; +function mxGetClipRegion; external; +function mxGetClip: boolean; external; +procedure mxGetImage; external; +procedure mxGetPalette( Palette: pointer; Start, Count: word ); external; +function mxGetPixel( X, Y: word ): byte; external; +procedure mxGetScreenSize( var Width, Height: word ); external; +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external; +function mxGetVersion: word; external; +procedure mxGetVirtualScreen( var Width, Height: word ); external; +procedure mxInit; external; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external; +procedure mxOutChar( X, Y: integer; C: char ); external; +procedure mxOutText( X, Y: integer; S: pointer ); external; +procedure mxPan( X, Y: word ); external; +procedure mxPutImage; external; +procedure mxPutPixel( X, Y: word; C: byte ); external; +procedure mxPutTile; external; +procedure mxReadPlane( Plane: byte ); external; +procedure mxRotatePalette; external; +procedure mxRowAddress( RowAddress: byte ); external; +function mxSetClip( Clip: boolean ): boolean; external; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external; +procedure mxSetColor( Index, R, G, B: word ); external; +procedure mxSetFont( Font: pointer; Width, Height: word ); external; +procedure mxSetMode( Mode: word ); external; +procedure mxSetPalette( Palette: pointer; Start, Count: word ); external; +procedure mxSetTextColor( Color, Op: word ); external; +procedure mxSetTextStep( DeltaX, DeltaY: integer ); external; +procedure mxSetVirtualScreen( Width, Height: word ); external; +procedure mxSplitScreen( Line: word ); external; +procedure mxStartAddress( StartAddress: word ); external; +procedure mxStartLine; external; +procedure mxStretchImage; external; +procedure mxTerm; external; +procedure mxTransPutTile; external; +procedure mxWaitDisplay; external; +procedure mxWaitRetrace; external; +procedure mxWriteMode( Mode: byte ); external; +procedure mxWritePlane( Plane: byte ); external; + +procedure mxFillPoly; external; +procedure mxGouraudPoly; external; +procedure mxTexturePoly; external; +{$L MXPB} +{$L MXPF} +{$L MXPG} +{$L MXPT} + +{$L MXBB} +{$L MXCC} +{$L MXCG} +{$L MXCL} +{$L MXCR} +{$L MXFB} +{$L MXFP} +{$L MXGI} +{$L MXGM} +{$L MXGP} +{$L MXGV} +{$L MXHL} +{$L MXIT} +{$L MXLN} +{$L MXOT} +{$L MXPI} +{$L MXPN} +{$L MXPP} +{$L MXRA} +{$L MXRP} +{$L MXSA} +{$L MXSC} +{$L MXSI} +{$L MXSL} +{$L MXSM} +{$L MXSP} +{$L MXSS} +{$L MXTL} +{$L MXVS} +{$L MXWD} +{$L MXWM} +{$L MXWP} +{$L MXWR} + +(* + Prints a Turbo Pascal string. + Note: BP 7.0 supports ASCIIZ strings (PChar type). +*) +procedure mxOutStr; +begin + S := S + #0; + mxOutText( X, Y, @S[1] ); +end; + +end. diff --git a/16/xw_/modex/DEMO01.EXE b/16/xw_/modex/DEMO01.EXE new file mode 100755 index 00000000..28caff88 Binary files /dev/null and b/16/xw_/modex/DEMO01.EXE differ diff --git a/16/xw_/modex/DEMO01.PAS b/16/xw_/modex/DEMO01.PAS new file mode 100755 index 00000000..c684acdd --- /dev/null +++ b/16/xw_/modex/DEMO01.PAS @@ -0,0 +1,126 @@ +(* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + MAX_SPRITE = 100; +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO02.EXE b/16/xw_/modex/DEMO02.EXE new file mode 100755 index 00000000..14e7dc72 Binary files /dev/null and b/16/xw_/modex/DEMO02.EXE differ diff --git a/16/xw_/modex/DEMO02.PAS b/16/xw_/modex/DEMO02.PAS new file mode 100755 index 00000000..6b4fb6f9 --- /dev/null +++ b/16/xw_/modex/DEMO02.PAS @@ -0,0 +1,125 @@ +(* + DEMO02 - Texture mapping and palette rotation + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Plasma, Threed; + +const + LSIZE = 85; + Trans : TPoint = ( X:0; Y:0; Z:0 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of T2DPoint; + Width : word; + Data : array[ 1..64*64 ] of byte; + end; + TQuad = record + VtxCnt : word; + Vtx : array[ 0..3 ] of word; + Texture: word; + end; +var + Vtx : array[ 0..7 ] of TPoint; + XVtx : array[ 0..7 ] of TPoint; + VVtx : array[ 0..7 ] of T2DPoint; + Face : array[ 0..5 ] of TQuad; + Txts : array[ 0..5 ] of TTexture; + Nrm : array[ 0..5 ] of TPoint; + XNrm : array[ 0..5 ] of TPoint; + Page : word; + Palette: array[ byte ] of record R, G, B: byte; end; + +(* Make a 64x64 plasma to be used as texture *) +procedure MakeTexture( Idx: word ); +var + I: word; +begin + mxFillBox( 0, 0, 64, 64, 0, OP_SET ); + MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 ); + mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 ); + (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *) + with Txts[Idx] do begin + Desc[0].X := $80; Desc[0].Y := $80; + Desc[1].X := $80; Desc[1].Y := $3F80; + Desc[2].X := $3F80; Desc[2].Y := $3F80; + Desc[3].X := $3F80; Desc[3].Y := $80; + Width := 64; + end; +end; + +procedure Init; +var + I: integer; +begin + (* Build vertexes for a cube *) + with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + for I:=0 to 7 do begin (* Make points 16:16 fixed *) + Vtx[I].X := Vtx[I].X*$10000; + Vtx[I].Y := Vtx[I].Y*$10000; + Vtx[I].Z := Vtx[I].Z*$10000; + end; + (* Build faces *) + with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end; + with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end; + with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end; + with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end; + with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end; + with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end; + for I:=0 to 5 do Face[I].Texture := I; + (* Build textures and palette *) + Randomize; + FillChar( Palette, SizeOf(Palette), 0 ); + MakePlasmaPalette( Palette, PAL_RGB ); + mxSetPalette( @Palette, 0, 193 ); + for I:=0 to 5 do MakeTexture( I ); +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, 8 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + mxRotatePalette( @Palette[1], 192, 3 ); (* Rotate palette *) + (* Draw cube: backface culling is straighforward in this case, so *) + (* it can be handled by the polygon filling procedure *) + for I:=0 to 5 do + mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width ); + mxStartLine( Page ); (* Flip pages *) + mxSetPalette( @Palette[1], 1, 192 ); (* Set new palette *) + Page := 240-Page; + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO03.EXE b/16/xw_/modex/DEMO03.EXE new file mode 100755 index 00000000..c646c4b0 Binary files /dev/null and b/16/xw_/modex/DEMO03.EXE differ diff --git a/16/xw_/modex/DEMO03.PAS b/16/xw_/modex/DEMO03.PAS new file mode 100755 index 00000000..01d10f49 --- /dev/null +++ b/16/xw_/modex/DEMO03.PAS @@ -0,0 +1,152 @@ +(* + DEMO03 - Simple star animation, morphs between a cube and a sphere + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 1000; (* Number of points *) + EDGE = 70; (* Length of cube edge *) + RADIUS = 90; (* Radius of sphere *) + WAITCOUNT = 192; (* Frames to wait for non-morphing shapes *) + MS = 32; (* Number of steps for morphing *) + Trans : TPoint = ( X:0; Y:0; Z:0 ); + InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 ); + InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS ); + InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 ); + InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 ); +type + T2DPoint = record + X, Y: integer; + end; + T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint; + P3DPointArray = ^T3DPointArray; +var + CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray; + VVtx : array[ 0..MAXVTX-1 ] of T2DPoint; + Page : word; + Status, Count, Delta1, Delta2, Morph1, Morph2: integer; + +procedure Swap( var A, B: longint ); +var + L: longint; +begin + L := A; A := B; B := L; +end; + +function Toggle( A: longint ): longint; +begin + Toggle := A; + if( Random(2) = 0 ) then Toggle := -A; +end; + +procedure Init; +label Retry; +var + I: integer; +begin + New( CubeVtx ); + New( SphereVtx ); + New( Vtx ); + New( XVtx ); + (* Build vertexes (yes, I know this piece of code is terrible) *) + Randomize; + for I:=0 to MAXVTX-1 do begin + with CubeVtx^[I] do begin + (* Build cube *) + X := (longint(Random(2*EDGE))-EDGE)*$10000; + Y := (longint(Random(2*EDGE))-EDGE)*$10000; + Z := Toggle( EDGE*$10000 ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + end; + with SphereVtx^[I] do begin + (* Build sphere *) +Retry: + X := (longint(Random(2*RADIUS))-RADIUS); + Y := (longint(Random(2*RADIUS))-RADIUS); + if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry; + Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + X := X * $10000; Y := Y * $10000; Z := Z * $10000; + end; + end; + (* Initialize morphing *) + Move( CubeVtx^, Vtx^, SizeOf(Vtx^) ); + Status := 0; + Count := WAITCOUNT; +end; + +procedure Morph; +var + I: integer; +begin + (* Fully unoptimized, slowest loop I could think of! *) + for I:=0 to MAXVTX-1 do begin + Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS; + Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS; + Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS; + end; +end; + +var + AX, AY, AZ: byte; + I: word; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + C := #0; + repeat + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx^, XVtx^, MAXVTX ); (* 3D transform points *) + tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw points *) + for I:=0 to MAXVTX-1 do + mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 ); + mxStartLine( Page ); (* Flip pages *) + Page := 240-Page; + (* Morph *) + if( Odd(Status) ) then begin + Morph; + Inc( Morph1, Delta1 ); + Inc( Morph2, Delta2 ); + if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status ); + if( Status = 4 ) then Status := 0; + end + else begin + Dec( Count ); + if( Count < 0 ) then begin + Inc( Status ); + Count := WAITCOUNT; + Morph1 := InitMorph1[Status]; + Morph2 := InitMorph2[Status]; + Delta1 := InitDelta1[Status]; + Delta2 := InitDelta2[Status]; + end; + end; + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO04.DAT b/16/xw_/modex/DEMO04.DAT new file mode 100755 index 00000000..72aaad08 Binary files /dev/null and b/16/xw_/modex/DEMO04.DAT differ diff --git a/16/xw_/modex/DEMO04.EXE b/16/xw_/modex/DEMO04.EXE new file mode 100755 index 00000000..1fec5e8a Binary files /dev/null and b/16/xw_/modex/DEMO04.EXE differ diff --git a/16/xw_/modex/DEMO04.PAS b/16/xw_/modex/DEMO04.PAS new file mode 100755 index 00000000..1a946315 --- /dev/null +++ b/16/xw_/modex/DEMO04.PAS @@ -0,0 +1,198 @@ +(* + DEMO04 - Multiple textures and triple buffering (3 pages) + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 256; + MAXCUB = 2; + MAXTXT = 2; + Trans : TPoint = ( X:0; Y:0; Z:0 ); + TxtSunDial: array[ 0..7 ] of word = ( + $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 ); + TxtSapphire : array[ 0..7 ] of word = ( + $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 ); + TxtMarble: array[ 0..7 ] of word = ( + $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of record X, Y: word end; + Width : word; + Data : pointer; + end; + TQuad = record + Vtx : array[ 0..3 ] of word; + Texture: word; + end; + TCube = record + Face : array[ 0..5 ] of TQuad; + Base : integer; + end; +var + Vtx, XVtx: array[ 0..MAXVTX ] of TPoint; + VVtx : array[ 0..MAXVTX ] of T2DPoint; + Cube : array[ 0..MAXCUB ] of TCube; + ZList : array[ 0..MAXCUB ] of integer; + VtxCnt : word; + Txts : array[ 0..MAXTXT ] of TTexture; + Page : word; + Palette : array[ byte ] of record R, G, B: byte; end; + TxtDat1, TxtDat2: pointer; + +(* Add a new entry to the vertex array *) +procedure AddVtx( PX, PY, PZ: longint ); +begin + with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end; + Inc( VtxCnt ); +end; + +procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer ); +const + FaceIdx: array[ 0..23 ] of integer = ( + 0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 ); +var + I, VC: integer; +begin + VC := VtxCnt; + C.Base := VC; + AddVtx( X1+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y2+TY, Z2+TZ ); + AddVtx( X1+TX, Y2+TY, Z2+TZ ); + for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I]; + for I:=0 to 5 do C.Face[I].Texture := Texture; +end; + +procedure MakeTexture( Idx: integer; var VtxData ); +var + P: ^word; + I: integer; +begin + P := @VtxData; + with Txts[Idx] do begin + for I:=0 to 3 do begin + Desc[I].X := P^; Inc( P ); + Desc[I].Y := P^; Inc( P ); + end; + Width := 129; + Data := TxtDat1; + end; +end; + +procedure Init; +var + I: integer; + V: integer; + F: file; + P: array[ 1..768 ] of byte; +begin + (* Initialize objects *) + VtxCnt := 0; + MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 ); (* Sundial *) + Cube[0].Face[0].Texture := 0; + V := VtxCnt; + MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *) + tdSetTranslation( Trans ); + tdSetRotation( 32, 32, 00 ); + tdRotate( Vtx[V], XVtx[V], 8 ); (* Got to rotate this cube *) + for I:=V to V+7 do begin + Vtx[I].X := XVtx[I].X; + Vtx[I].Y := XVtx[I].Y; + Vtx[I].Z := XVtx[I].Z + 100*$10000; + end; + MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *) + (* Load texture and palette *) + Assign( F, 'DEMO04.DAT' ); + Reset( F, 1 ); + BlockRead( F, P, SizeOf(P) ); + mxSetPalette( @P, 0, 256 ); + GetMem( TxtDat1, 63*1024 ); + BlockRead( F, TxtDat1^, 129*286 ); + Close( F ); + TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 ); + (* Init textures *) + MakeTexture( 0, TxtSundial ); + MakeTexture( 1, TxtMarble ); + MakeTexture( 2, TxtSapphire ); + Txts[2].Data := TxtDat2; +end; + +(* Sort procedure, not worth optimizing with only a few objects *) +procedure SortObjects; +var + I, J, K: integer; + ZMax: array[ 0..MAXCUB ] of longint; + ZI: integer; + L: longint; +begin + for I:=0 to MAXCUB do begin + L := XVtx[Cube[I].Base].Z; + for J:=1 to 7 do + if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z; + ZMax[I] := L; + ZList[I] := I; + end; + for I:=0 to MAXCUB-1 do begin + ZI := I; + for J:=I+1 to MAXCUB do + if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J; + if( ZI <> I ) then begin + K := ZList[I]; + ZList[I] := ZList[ZI]; + ZList[ZI] := K; + end; + end; +end; + +var + AX, AY, AZ: byte; + I, J, K: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + (* Init 3D transforms, perspective is intentionally exaggerated *) + AX := 0; AY := 0; AZ := 0; + tdSetTranslation( Trans ); + tdSetPerspective( 600*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, VtxCnt ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 1 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw objects *) + SortObjects; + for I:=0 to MAXCUB do with Cube[ZList[I]] do begin + for J:=0 to 5 do begin + K := Face[J].Texture; + mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width ); + end; + end; + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* If the frame rate seems low, try to remove this line *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO05.EXE b/16/xw_/modex/DEMO05.EXE new file mode 100755 index 00000000..21a7c207 Binary files /dev/null and b/16/xw_/modex/DEMO05.EXE differ diff --git a/16/xw_/modex/DEMO05.PAS b/16/xw_/modex/DEMO05.PAS new file mode 100755 index 00000000..819c5cf3 --- /dev/null +++ b/16/xw_/modex/DEMO05.PAS @@ -0,0 +1,131 @@ +(* + DEMO05 - A Gouraud-shaded rotating torus + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex, Threed; + +(* Define ALTPAL for alternate palette *) +{$define ALTPAL} + +const + MAXVTX1 = 15; RADIUS1 = 70; (* MAXVTX1+1 must be multiple of 4 *) + MAXVTX2 = 15; RADIUS2 = 30; + MAXVTX = (MAXVTX1+1)*(MAXVTX2+1)-1; + MAXFACE = MAXVTX; + Trans : TPoint = ( X:0; Y:0; Z:0 ); (* Object translation *) + Light : TPoint = ( X:0; Y:0; Z:-63*$10000 ); (* Light direction *) +type + TQuad = record + QVtx : array[ 0..3 ] of integer; + end; +var + Vtx, XVtx : array[ 0..MAXVTX ] of TPoint; (* Points *) + VVtx : array[ 0..MAXVTX ] of record X, Y: integer end; + Face : array[ 0..MAXFACE ] of TQuad; (* Polys *) + Culled : array[ 0..MAXFACE ] of integer; + GNrm,XGNrm: array[ 0..MAXVTX ] of TVector; (* Gouraud normals *) + VtxLight : array[ 0..MAXVTX ] of integer; (* Points brightness *) + Page : word; + +function GetVtx( I1, I2: integer ): integer; +begin + GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1); +end; + +procedure Init; +var + R, N, X, Y, Z: real; + I, J, K, V: integer; +begin + (* Build vertexes *) + for I:=0 to MAXVTX1 do begin + K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1); + R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) ); + for J:=0 to MAXVTX2 do begin + V := I*(MAXVTX2+1)+J; (* Index of current vertex *) + (* Compute coordinates of current vertex *) + X := R*Cos(2*J*Pi / (MAXVTX2+1)); (* Get coordinates *) + Y := R*Sin(2*J*Pi / (MAXVTX2+1)); + Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1)); + Vtx[V].X := Round( X )*$10000; (* Save coordinates *) + Vtx[V].Y := Round( Y )*$10000; + Vtx[V].Z := Round( Z )*$10000; + (* Compute direction of Gouraud normal thru current vertex *) + X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1)); + Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1)); + N := Sqrt( X*X + Y*Y + Z*Z ); (* Get vector length *) + GNrm[V].X := Trunc( X*$10000/N ); (* Save normal vector *) + GNrm[V].Y := Trunc( Y*$10000/N ); + GNrm[V].Z := Trunc( Z*$10000/N ); + end; + end; + (* Generate faces so that depth-sorting is not needed: there are still *) + (* some *very* little errors, but this is the best I could devise *) + J := 0; + K := 0; + for I:=0 to MAXFACE do with Face[I] do begin + QVtx[0] := GetVtx( J, K ); + QVtx[1] := GetVtx( J, K+1 ); + QVtx[2] := GetVtx( J+1, K+1 ); + QVtx[3] := GetVtx( J+1, K ); + Inc( K ); + if( K > MAXVTX2 ) then begin + K := 0; + Inc( J ); + end; + end; +{$ifndef ALTPAL} + for I:=0 to 63 do mxSetColor( I+64, 0, 0, I ); (* Blue palette *) +{$else} + for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *) + for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 ); +{$endif} +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetLight( Light ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, MAXVTX+1 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page ); + tdRotate( GNrm, XGNrm, MAXVTX+1 ); (* Rotate Gouraud normals *) + tdTransformLight( XGNrm, VtxLight, MAXVTX+1 ); + (* Backplane culling is not really needed here! *) + FillChar( Culled, SizeOf(Culled), 0 ); + tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 3 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw polygons *) + for I:=0 to MAXFACE do with Face[I] do + if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 ); + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* Uncomment this instruction if screen flickers *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO06.DAT b/16/xw_/modex/DEMO06.DAT new file mode 100755 index 00000000..1ac2c2bb Binary files /dev/null and b/16/xw_/modex/DEMO06.DAT differ diff --git a/16/xw_/modex/DEMO06.EXE b/16/xw_/modex/DEMO06.EXE new file mode 100755 index 00000000..f1308e8a Binary files /dev/null and b/16/xw_/modex/DEMO06.EXE differ diff --git a/16/xw_/modex/DEMO06.PAS b/16/xw_/modex/DEMO06.PAS new file mode 100755 index 00000000..f26af067 --- /dev/null +++ b/16/xw_/modex/DEMO06.PAS @@ -0,0 +1,135 @@ +(* + DEMO06 - Magnifying glass + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + R = 40; (* Lens radius *) + K : real = 1.8; (* Magnifying factor, less makes a stronger lens *) +type + TLine = array[ 0..319 ] of byte; + PLine = ^TLine; + TScreen = array[ 0..239 ] of PLine; +var + VScreen: TScreen; (* Virtual screen *) + BallX : array[ 0..R, 0..R ] of integer; + BallY : array[ 0..R, 0..R ] of integer; + Sprite : array[ -R..R, -R..R ] of byte; + Page : word; + +(* Returns "lens-view" coordinates of X,Y *) +procedure GetCoords( var X, Y: integer ); +var + LR, Z, SinA, SinB, TgB, Q: real; +begin + LR := Sqrt( X*X + Y*Y ); + if( LR = 0 ) then Exit; + if( LR < R ) then begin + Z := Sqrt( R*R - LR*LR ); + SinA := LR / R; + SinB := SinA / K; + TgB := SinB / Sqrt( 1-SinB*SinB ); + Q := LR - TgB*Z; + X := Round( X * ( Q/LR ) ); + Y := Round( Y * ( Q/LR ) ); + end; +end; + +procedure Init; +var + F : file; + Palette: array[ 0..767 ] of record R, G, B: byte; end; + X, Y, + X2, Y2 : integer; +begin + (* Load background image *) + Assign( F, 'demo06.dat' ); + Reset( F, 1 ); + BlockRead( F, Palette, 768 ); + mxSetPalette( @Palette, 0, 256 ); + for Y:=0 to 239 do begin + New( VScreen[Y] ); + BlockRead( F, VScreen[Y]^, 320 ); + mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE ); + end; + Close( F ); + (* Build lens *) + for X:=0 to R do begin + for Y:=0 to R do begin + X2 := X; + Y2 := Y; + GetCoords( X2, Y2 ); + BallX[X, Y] := X2; + BallY[X, Y] := Y2; + end; + end; +end; + +procedure PutLens( OX, OY: integer ); +var + X, Y: integer; +begin + for X:=0 to R do begin + for Y:=0 to R do begin + Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + end; + end; + (* Draw the sprite *) + mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE ); +end; + +function Delta: integer; +begin + Delta := Random(3)+2; +end; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*Delta; + end; +end; + +var + X, Y, DX, DY: integer; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; + X := R; + Y := R; + Randomize; + DX := Delta; + DY := Delta; + + (* Main loop *) + repeat + (* Update video *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + PutLens( X, Y ); + mxCircle( X, Page+Y, R, 0 ); + (* Update lens coordinates *) + Inc( X, DX ); + Check( X+R >= 319, X, DX, 319-R, -1 ); + Check( X <= R, X, DX, R, +1 ); + Inc( Y, DY ); + Check( Y+R >= 239, Y, DY, 239-R, -1 ); + Check( Y <= R, Y, DY, R, +1 ); + (* Flip pages: double buffering, avoid wait for display *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 0; end; + end; + mxWaitRetrace; (* Wait for hidden page to show *) + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/DEMO07.EXE b/16/xw_/modex/DEMO07.EXE new file mode 100755 index 00000000..8a401169 Binary files /dev/null and b/16/xw_/modex/DEMO07.EXE differ diff --git a/16/xw_/modex/DEMO07.PAS b/16/xw_/modex/DEMO07.PAS new file mode 100755 index 00000000..04fff790 --- /dev/null +++ b/16/xw_/modex/DEMO07.PAS @@ -0,0 +1,68 @@ +(* + DEMO07 - Hardware scrolling + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + (* Change this if scrolling seems jerky (this simple program does *) + (* not handle vertical retrace/display very well) *) + STEPS = 5; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*(Random(3)+2); + end; +end; + +var + I, X, Y, DX, DY: integer; +begin + (* Initialize library and graphics mode *) + mxInit; + mxSetMode( MX_320x200 ); + (* Set a 640x400 virtual screen *) + mxSetVirtualScreen( 640, 400 ); + mxSetClip( TRUE ); + + X := 0; + Y := 0; + DX := 1; + DY := 1; + + (* Main loop: draw lines, circles, points and rectangles in separate *) + (* 320x200 windows, while smoothly panning virtual screen *) + while( not KeyPressed ) do begin + (* Points *) + mxSetClipRegion( 0, 0, 320, 200 ); + for I:=1 to STEPS do + mxPutPixel( Random(320), Random(200), Random(16) ); + (* Lines *) + mxSetClipRegion( 0, 200, 320, 200 ); + for I:=1 to STEPS do + mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET ); + (* Circles *) + mxSetClipRegion( 320, 0, 320, 200 ); + for I:=1 to STEPS do + mxCircle( Random(320)+320, Random(200), Random(100), Random(16) ); + (* Boxes *) + mxSetClipRegion( 320, 200, 320, 200 ); + for I:=1 to STEPS do + mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET ); + (* Pan *) + Inc( X, DX ); + Check( X+320 >= 639, X, DX, 319, -1 ); + Check( X < 0, X, DX, 0, +1 ); + Inc( Y, DY ); + Check( Y+200 >= 399, Y, DY, 199, -1 ); + Check( Y < 0, Y, DY, 0, +1 ); + mxPan( X, Y ); + mxWaitRetrace; + end; + + (* Shutdown *) + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/MATH.INC b/16/xw_/modex/MATH.INC new file mode 100755 index 00000000..742af410 --- /dev/null +++ b/16/xw_/modex/MATH.INC @@ -0,0 +1,34 @@ +; +; MATH.INC - Include file for THREED.ASM +; + +; 3-dimensional point, coordinates in fixed format (16:16) +; +TPOINT STRUC + X DD ? + Y DD ? + Z DD ? +TPOINT ENDS + +; 2-dimensional point, coordinates in integer format +; +TIMAGEPOINT STRUC + IX DW ? + IY DW ? +TIMAGEPOINT ENDS + +; Fixed-point divide: EAX = EAX / arg +; +.xdiv MACRO arg + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv arg +ENDM + +; Fixed-point multiply: EAX = EAX * arg +; +.xmul MACRO arg + imul arg + shrd eax, edx, 16 +ENDM diff --git a/16/xw_/modex/PLASMA.PAS b/16/xw_/modex/PLASMA.PAS new file mode 100755 index 00000000..237e292a --- /dev/null +++ b/16/xw_/modex/PLASMA.PAS @@ -0,0 +1,103 @@ +unit Plasma; +interface + +const + PAL_RGB = 0; + PAL_CLOUDS = 1; + PAL_LANDSCAPE = 2; + +procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte ); +procedure MakePlasmaPalette( var Palette; What: word ); + +implementation uses Modex; + +procedure NewColor( XA, YA, X, Y, XB, YB: integer ); +var + Color: longint; +begin + Color := Abs( XA-XB )+Abs( YA-YB ); + Color := Random( Color shl 1 )-Color; + Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1; + if( Color < 1 ) then Color := 1; + if( Color > 192 ) then Color := 192; + if( mxGetPixel( X, Y ) = 0 ) then + mxPutPixel( X, Y, Lo(Color) ); +end; + +procedure Divide( X1, Y1, X2, Y2: integer ); +var + X, Y, Color: integer; +begin + if not( (X2-X1<2)and(Y2-Y1<2) ) then begin + X := (X1+X2) shr 1; + Y := (Y1+Y2) shr 1; + NewColor( X1, Y1, X, Y1, X2, Y1 ); + NewColor( X2, Y1, X2, Y, X2, Y2 ); + NewColor( X1, Y2, X, Y2, X2, Y2 ); + NewColor( X1, Y1, X1, Y, X1, Y2 ); + Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+ + mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2; + mxPutPixel( X, Y, Color ); + Divide( X1, Y1, X, Y ); + Divide( X, Y1, X2, Y ); + Divide( X, Y, X2, Y2 ); + Divide( X1, Y, X, Y2 ); + end; +end; + +procedure MakePlasma; +begin + Dec( W ); + Dec( H ); + mxPutPixel( X, Y, C1 ); + mxPutPixel( X, Y+H, C2 ); + mxPutPixel( X+W, Y+H, C3 ); + mxPutPixel( X+W, Y, C4 ); + Divide( X, Y, X+W, Y+H ); +end; + +procedure MakePlasmaPalette; +type + TPal = array[ byte ] of record R, G, B: byte end; +var + I: word; +begin + FillChar( TPal(Palette)[1], 192*3, 0 ); + case What of + PAL_CLOUDS: + for I:=1 to 192 do begin + TPal(Palette)[I].R := Abs( I-96 )*63 div 96; + TPal(Palette)[I].G := Abs( I-96 )*63 div 96; + TPal(Palette)[I].B := 63; + end; + PAL_LANDSCAPE: + begin + for I:=0 to 31 do begin + TPal(Palette)[I+1].R := I; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := I + I shr 1+15; + end; + for I:=32 to 63 do begin + TPal(Palette)[I+1].R := 0; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := 0; + end; + for I:=64 to 191 do begin + TPal(Palette)[I+1].R := (I-64) div 3 + 15; + TPal(Palette)[I+1].G := (I-64) div 3 + 15; + TPal(Palette)[I+1].B := (I-64) div 3 + 15; + end; + end; + else + for I:=1 to 64 do begin + TPal(Palette)[I].G := I-1; + TPal(Palette)[I].B := 64-I; + TPal(Palette)[I+64].R := I-1; + TPal(Palette)[I+64].G := 64-I; + TPal(Palette)[I+128].B := I-1; + TPal(Palette)[I+128].R := 64-I; + end; + end; +end; + +end. \ No newline at end of file diff --git a/16/xw_/modex/QIX2.EXE b/16/xw_/modex/QIX2.EXE new file mode 100755 index 00000000..a10d7db5 Binary files /dev/null and b/16/xw_/modex/QIX2.EXE differ diff --git a/16/xw_/modex/QIX2.PAS b/16/xw_/modex/QIX2.PAS new file mode 100755 index 00000000..d1b59791 --- /dev/null +++ b/16/xw_/modex/QIX2.PAS @@ -0,0 +1,210 @@ +{$E-,N+} +uses Crt, Modex; + +const + DEFVERT = 12; (* Vertex count *) + DEFREPL = 3; (* Repetition count *) + DEFQIXS = 2; (* Qixs *) + FADESPEED = 48; +type + TPoint = record + X, Y : integer; + end; + TRGB = record + R, G, B: byte; + end; + TQix = record + Color: integer; + Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint; + Delta: array[ 0..DEFVERT-1 ] of TPoint; + end; +var + Page : integer; + MaxX, + MaxY : word; + Qix : array[ 0..DEFQIXS-1 ] of TQix; + Pal : array[ byte ] of TRGB; + +type + TReal = double; + TRPoint = record + X, Y: TReal; + end; + TMatrix = array[ 0..3, 0..3 ] of TReal; +var + M: TMatrix; + G: array[ 0..DEFVERT-1 ] of TRPoint; + C: array[ 0..DEFVERT-1 ] of TRPoint; + +procedure BumpPal( Idx, DR, DG, DB, Steps: integer ); +var + I: integer; +begin + for I:=1 to Steps do begin + Pal[Idx+1].R := Pal[Idx].R + DR; + Pal[Idx+1].G := Pal[Idx].G + DG; + Pal[Idx+1].B := Pal[Idx].B + DB; + Inc( Idx ); + end; +end; + +procedure InitPalette; +begin + with Pal[0] do begin R:=0; G:=0; B:=0; end; + with Pal[1] do begin R:=0; G:=0; B:=62; end; + BumpPal( 1, 0, 2, -2, 31 ); + BumpPal( 32, 2, -2, 0, 31 ); + BumpPal( 63, -2, 2, 2, 31 ); + BumpPal( 94, 2, 0, -2, 31 ); + BumpPal( 125, -2, -2, 2, 31 ); +end; + +procedure Init( var Qix: TQix; Color: integer ); +var + I: integer; +begin + FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 ); + for I:=0 to DEFVERT-1 do begin + Qix.Vert[I, DEFREPL-1].X := Random( MaxX ); + Qix.Vert[I, DEFREPL-1].Y := Random( MaxY ); + Qix.Delta[I].X := Random(5)+1; + Qix.Delta[I].Y := Random(5)+1; + end; + Qix.Color := Color; + + (* Initialize matrix (Catmull-Rom) *) + M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2; + M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2; + M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0; + M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0; +end; + +procedure mxBezier( var Qix: TQix; I0, Idx, N: integer ); +var + I, J: integer; + T, T2, T3: TReal; + X0, Y0, X, Y: TReal; + Delta: TReal; +begin + (* Compute coefficients *) + for I:=0 to 3 do begin + C[I].X := 0; + for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X; + C[I].Y := 0; + for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y; + end; + X0 := C[3].X; + Y0 := C[3].Y; + Delta := 1 / N; + T := 0; + for I:=1 to N do begin + T := T + Delta; + T2 := T*T; + T3 := T*T2; + X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X; + Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y; + mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET ); + X0 := X; + Y0 := Y; + end; +end; + +procedure Plot( var Qix: TQix; Idx: integer ); +var + I, J: integer; +begin + for I:=0 to DEFVERT-1 do begin + mxBezier( Qix, I, Idx, 12 ); + end; +end; + +procedure Update( var Qix: TQix; Idx: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Inc( Vert[I,Idx].X, Delta[I].X ); + if( Vert[I,Idx].X < 0 ) then begin + Vert[I,Idx].X := 0; + Delta[I].X := Random( 5 )+1; + end; + if( Vert[I,Idx].X > MaxX ) then begin + Vert[I,Idx].X := MaxX; + Delta[I].X := -Random( 5 )-1; + end; + Inc( Vert[I,Idx].Y, Delta[I].Y ); + if( Vert[I,Idx].Y < 0 ) then begin + Vert[I,Idx].Y := 0; + Delta[I].Y := Random( 5 )+1; + end; + if( Vert[I,Idx].Y > MaxY ) then begin + Vert[I,Idx].Y := MaxY; + Delta[I].Y := -Random( 5 )-1; + end; + end; +end; + +procedure Copy( var Qix: TQix; Dest, Src: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Vert[I,Dest].X := Vert[I,Src].X; + Vert[I,Dest].Y := Vert[I,Src].Y; + end; +end; + +procedure AnimateQix; +var + Q, Idx, I, J, P, Count: integer; +begin + Count := 0; + P := DEFREPL-1; + I := 0; + J := 1; + repeat + mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 ); + mxSetClip( TRUE ); + mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET ); + for Q:=0 to DEFQIXS-1 do begin + Copy( Qix[Q], I, P ); + Update( Qix[Q], I ); + for Idx:=0 to DEFREPL-1 do begin + Plot( Qix[Q], Idx ); + end; + end; + I := (I+1) mod DEFREPL; + J := (J+1) mod DEFREPL; + P := (P+1) mod DEFREPL; + Inc( Count ); + mxStartLine( Page ); + if( Count >= FADESPEED ) then begin + for Q:=0 to DEFQIXS-1 do begin + Inc( Qix[Q].Color ); + if( Qix[Q].Color > 156 ) then + Qix[Q].Color := 1; + end; + Count := 0; + end; + Page := 240-Page; + until( KeyPressed ); +end; + +var + I: integer; +begin + Randomize; + mxInit; + mxSetMode( MX_320x240 ); + mxGetScreenSize( MaxX, MaxY ); + for I:=0 to DEFQIXS-1 do + Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 ); + InitPalette; + mxSetPalette( @Pal, 0, 157 ); + Page := 240; + Dec( MaxX ); + Dec( MaxY ); + AnimateQix; + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw_/modex/README.TXT b/16/xw_/modex/README.TXT new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw_/modex/README.TXT @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw_/modex/SINCOS.INC b/16/xw_/modex/SINCOS.INC new file mode 100755 index 00000000..6986eeeb --- /dev/null +++ b/16/xw_/modex/SINCOS.INC @@ -0,0 +1,518 @@ +; +; SINCOS.INC - Sin/cos tables for THREED.ASM +; + +tblSin LABEL DWORD + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 +tblCos LABEL DWORD + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 diff --git a/16/xw_/modex/THREED.ASM b/16/xw_/modex/THREED.ASM new file mode 100755 index 00000000..5ecd3ba3 --- /dev/null +++ b/16/xw_/modex/THREED.ASM @@ -0,0 +1,872 @@ +COMMENT / + Fixed-point math functions and 3D transforms + Copyright (c) 1993,94 by Alessandro Scotti +/ +WARN PRO +P386 +JUMPS +LOCALS + +INCLUDE MATH.INC + +PUBLIC tdFixedMul +PUBLIC tdGetNormal +PUBLIC tdRotate +PUBLIC tdGetSurfaceLight +PUBLIC tdSetLight +PUBLIC tdSetRotation +PUBLIC tdSetTranslation +PUBLIC tdTransform +PUBLIC tdTransformToImage +PUBLIC tdTransformLight +PUBLIC tdBackPlaneCull +PUBLIC tdSetPerspective + +;----------------------------------------------------------- +; +; Data segment +; +MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' + ASSUME ds:MATH_DATA + +INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table + +XRotation TPOINT <> ; 3x3 rotation matrix +YRotation TPOINT <> +ZRotation TPOINT <> + +Translation TPOINT <> ; Translation vector + +Light TPOINT <> ; Light vector +AmbientLight DW 00 ; Ambient light + +XScale DD 10000h ; Scaling factor for X coordinate +YScale DD 10000h ; Scaling factor for Y coordinate +PerspectiveDistance DD 20000000h + +MATH_DATA ENDS + +;----------------------------------------------------------- +; +; Code segment +; +MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING + +tdSetPerspective PROC PASCAL FAR + ARG Perspective:DWORD, \ + ScaleX:DWORD, \ + ScaleY:DWORD + USES ds + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov eax, [Perspective] + mov [PerspectiveDistance], eax + mov eax, [ScaleX] + mov [XScale], eax + mov eax, [ScaleY] + mov [YScale], eax + + ret +tdSetPerspective ENDP + + +;----------------------------------------------------------- +; +; Sets the rotation matrix. +; +; Input: +; RX = X-axis rotation angle +; RY = X-axis rotation angle +; RZ = X-axis rotation angle +; Output: +; none +; +tdSetRotation PROC PASCAL FAR + ARG RX:WORD, \ + RY:WORD, \ + RZ:WORD + USES ds, si, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov bx, [RZ] + mov si, [RY] + mov di, [RX] + shl bx, 2 + shl si, 2 + shl di, 2 + + push ebp ; We use EBP as a scratch register + +; Set X rotation + mov eax, tblCos[bx] + imul tblCos[si] + mov [XRotation.X], edx + + mov eax, tblSin[bx] + imul tblCos[si] + mov [XRotation.Y], edx + + mov eax, tblSin[si] + sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 + mov [XRotation.Z], eax + +; Set Y rotation + mov eax, tblCos[bx] + imul tblSin[si] ; EDX:EAX = fixed 16:48 + shrd eax, edx, 24 ; EAX = fixed 8:24 + imul tblSin[di] ; EDX:EAX = fixed 16:48 + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblCos[di] + add eax, ebp + adc edx, ecx ; EDX:EAX = fixed 16:48 + neg edx + mov [YRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblSin[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblCos[di] + sub eax, ebp + sbb edx, ecx + mov [YRotation.Y], edx + + mov eax, tblCos[si] + imul tblSin[di] + mov [YRotation.Z], edx + +; Set Z rotation + mov eax, tblCos[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblSin[di] + sub eax, ebp + sbb edx, ecx + mov [ZRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblSin[di] + add eax, ebp + add edx, ecx + neg edx + mov [ZRotation.Y], edx + + mov eax, tblCos[si] + imul tblCos[di] + mov [ZRotation.Z], edx + + pop ebp ; Restore EBP + + ret +tdSetRotation ENDP + +;----------------------------------------------------------- +; +; Sets the translation vector. +; +; Input: +; TV = pointer to translation vector +; Output: +; none +; +tdSetTranslation PROC PASCAL FAR + ARG TV:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [TV] + mov eax, es:[di].X + mov [Translation.X], eax + mov eax, es:[di].Y + mov [Translation.Y], eax + mov eax, es:[di].Z + mov [Translation.Z], eax + + ret +tdSetTranslation ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdTransform PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + LOCAL Adjust:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + + ALIGN DWORD +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + mov ebx, eax + shrd eax, edx, 16 + add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) + mov es:[di].Z, eax +; Get perspective factor + mov ebx, [PerspectiveDistance] + sub eax, ebx + neg eax ; EAX = PD - Z + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv ebx ; EAX = fixed 16:16 result + mov [Adjust], eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.X] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.Y] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdTransform ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT into an array of TIMAGEPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TIMAGEPOINT +; Count = number of entries to transform +; DeltaX = translation distance for the X coordinate +; DeltaY = translation distance for the Y coordinate +; Output: +; the maximum Z value +; +tdTransformToImage PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD + LOCAL Adjust:DWORD, \ + Max:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + mov [Max], 80000000h + +@@Loop: +; Check max Z + mov eax, fs:[si].Z + cmp eax, [Max] + jle @@1 + mov [Max], eax +@@1: + +; Transform X coordinate + mov ax, WORD PTR fs:[si].X[2] + add ax, [DeltaX] + mov es:[di].IX, ax + +; Transform Y coordinate + mov ax, WORD PTR fs:[si].Y[2] + add ax, [DeltaY] + mov es:[di].IY, ax + + add si, SIZE TPOINT + add di, SIZE TIMAGEPOINT + dec [Count] + jnz @@Loop + + mov eax, [Max] + shld edx, eax, 16 + ret +tdTransformToImage ENDP + +;----------------------------------------------------------- +; +; Sets the light source. +; +; Input: +; Light = pointer to light vector +; Output: +; none +; +tdSetLight PROC PASCAL FAR + ARG L:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [L] + mov eax, es:[di].X + mov [Light.X], eax + mov eax, es:[di].Y + mov [Light.Y], eax + mov eax, es:[di].Z + mov [Light.Z], eax + + ret +tdSetLight ENDP + +;----------------------------------------------------------- +; +; Computes light intensity for an array of surfaces. +; +; Input: +; Normals = pointer to an array of surface normals +; Lights = pointer to an array of integer to be filled with +; light intensity +; Count = number of elements to transform +; Output: +; none +; +tdTransformLight PROC PASCAL FAR + ARG Normals:DWORD, \ + Lights:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov fs, ax + ASSUME fs:MATH_DATA + + lds si, [Normals] + les di, [Lights] + ASSUME ds:NOTHING + +; Intensity is given by the dot product between the Light vector and +; the surface normal +@@Loop: + mov eax, ds:[si].Z + imul [Light.Z] + mov ebx, eax + mov ecx, edx + mov eax, ds:[si].Y + imul [Light.Y] + add ebx, eax + adc ecx, edx + mov eax, ds:[si].X + imul [Light.X] + add eax, ebx + adc edx, ecx ; EDX:EAX = fixed 32:32 intensity + add dx, [AmbientLight] + test dx, dx + jg @@1 + xor dx, dx ; Return 0 for no light +@@1: + mov es:[di], dx + inc di + inc di + add si, SIZE TPOINT + dec [Count] + jnz @@Loop + + ASSUME fs:NOTHING + ret +tdTransformLight ENDP + +;----------------------------------------------------------- +; +; Returns the light value given the normal to a surface. +; +; Input: +; Normal = pointer to TPOINT surface normal vector +; Output: +; AX = light intensity (>=0) +; Notes: +; the normal is rotated according to the current setting. +; +tdGetSurfaceLight PROC PASCAL FAR + ARG Normal:DWORD + USES ds, esi, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [Normal] + +; Transform Z coordinate + mov eax, es:[di].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.Z] + shrd eax, edx, 16 + mov esi, eax + +; Transform X coordinate + mov eax, es:[di].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add esi, eax + +; Transform Y coordinate + mov eax, es:[di].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add eax, esi + shr eax, 16 + +; Add ambient light + add ax, [AmbientLight] + test ax, ax + jge @@Exit + xor ax, ax + +@@Exit: + ret +tdGetSurfaceLight ENDP + +;----------------------------------------------------------- +; +; Rotates an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdRotate PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Z, eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdRotate ENDP + +tdFixedMul PROC PASCAL FAR + ARG F1:DWORD, \ + F2:DWORD + + mov eax, [F1] + imul [F2] + shr eax, 16 + + ret +tdFixedMul ENDP + +;----------------------------------------------------------- +; +; Returns in EAX the square root of EDX:EAX. +; +subSqrt PROC NEAR + push esi + push edi + + add eax, eax + adc edx, 0 + mov eax, edx ; Just discard the low bits + + mov esi, eax + xor edi, edi + shld edi, esi, 16 + shl esi, 16 +@@Loop: + mov ebx, eax + mul eax + add eax, esi + adc edx, edi + shrd eax, edx, 1 + shr edx, 1 + div ebx + cmp eax, ebx + jne @@Loop + +; Adjust EAX + shl eax, 8 + + pop edi + pop esi + ret +subSqrt ENDP + +;----------------------------------------------------------- +; +; Finds the unitary normal to a given surface. +; +; Input: +; Dest = pointer to TPOINT (vector) result +; P1, P2, P3 = pointer to TPOINT points on surface +; Output: +; none +; Notes: +; the normal is given by the cross-product between (P3-P1) and +; (P2-P1), so its orientation depends on the parameters order. +; +tdGetNormal PROC PASCAL FAR + ARG Dest:DWORD, \ + P1:DWORD, \ + P2:DWORD, \ + P3:DWORD + LOCAL V1:TPOINT, \ + V2:TPOINT, \ + N:TPOINT + USES ds, si, es, di + +; Get vector V1 + lds si, [P1] + les di, [P3] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V1.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V1.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V1.Z], eax + +; Get vector V2 + les di, [P2] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V2.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V2.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V2.Z], eax + +; Get normal vector (V1 x V2) + mov eax, [V1.Z] + imul [V2.Y] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Y] + imul [V2.Z] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.X], eax + + mov eax, [V1.X] + imul [V2.Z] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Z] + imul [V2.X] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Y], eax + + mov eax, [V1.Y] + imul [V2.X] + mov ebx, eax + mov ecx, edx + mov eax, [V1.X] + imul [V2.Y] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Z], eax + +; Get normal length + mov eax, [N.X] + imul eax + mov ebx, eax + mov ecx, edx + mov eax, [N.Y] + imul eax + add ebx, eax + adc ecx, edx + mov eax, [N.Z] + imul eax + add eax, ebx + adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z + call subSqrt ; EAX = normal length + mov ebx, eax + +; Adjust vector and save it + les di, [Dest] + mov eax, [N.X] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].X, eax + mov eax, [N.Y] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Y, eax + mov eax, [N.Z] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Z, eax + + ret +tdGetNormal ENDP + +TPOLY STRUC + Vtx DW 4 DUP(?) +TPOLY ENDS + +;----------------------------------------------------------- +; +; Performs surface removal on an array of polygons. +; +; Input: +; Poly = pointer to an array of TPOLY +; Vertex = pointer to an array of TPOINT +; Dest = pointer to an array of integer +; Count = number of polygons to check +; Step = size of TPOLY structure +; Output: +; if the n-th polygon is invisible the n-th entry of the +; Dest array is set to -1, other entries are not modified +; (so it's possible to use the Light array for Dest, because +; the light intensity is always >= 0) +; +tdBackPlaneCull PROC PASCAL FAR + ARG Step:WORD, \ + Poly:DWORD, \ + Vertex:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + ASSUME ds:NOTHING + + mov ds, WORD PTR Vertex[2] + les di, [Poly] + mov fs, WORD PTR Dest[2] + +@@Loop: + mov ax, es:[di].Vtx[2] ; Index of 2nd vertex + shl ax, 2 + mov bx, ax + shl ax, 1 + add bx, ax ; BX = index*SIZE TPOINT + add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex + mov ax, es:[di].Vtx[4] ; Index of 3rd vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex + mov ecx, ds:[si].X + sub ecx, ds:[bx].X ; ECX = V3.X-V2.X + mov edx, ds:[si].Y + sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y + mov ax, es:[di].Vtx[0] ; Index of 1st vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 1st vertex + mov eax, ds:[si].X + sub eax, ds:[bx].X ; EAX = V1.X-V2.X + mov esi, ds:[si].Y + sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y + imul edx + mov ebx, eax + xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) + mov eax, esi + imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) + sub eax, ebx + sbb edx, ecx + jl @@Next ; Polygon is visible + mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry + mov WORD PTR fs:[bx], -1 ; Remove polygon +@@Next: + add WORD PTR [Dest], 2 ; Next entry for dest + add di, [Step] ; Next polygon + dec [Count] + jnz @@Loop + + ret +tdBackPlaneCull ENDP + +MATH_TEXT ENDS +END diff --git a/16/xw_/modex/THREED.H b/16/xw_/modex/THREED.H new file mode 100755 index 00000000..b993ef86 --- /dev/null +++ b/16/xw_/modex/THREED.H @@ -0,0 +1,32 @@ +typedef struct { + long x, y, z; +} TVECTOR; + +#define PVECTOR TVECTOR far * + +#define TPOINT TVECTOR +#define PPOINT PVECTOR + +#define VPTR void far * + +#ifdef __cplusplus +extern "C" { +#endif + +long far pascal tdFixedMul( long, long ); +int far pascal tdGetSurfaceLight( PPOINT ); +long far pascal tdTransformToImage( VPTR, VPTR, short, short, short ); + +void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short ); +void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT ); +void far pascal tdRotate( VPTR, VPTR, short ); +void far pascal tdSetLight( PVECTOR ); +void far pascal tdSetRotation( short, short, short ); +void far pascal tdSetTranslation( PVECTOR ); +void far pascal tdSetPerspective( long, long, long ); +void far pascal tdTransform( VPTR, VPTR, short ); +void far pascal tdTransformLight( VPTR, VPTR, short ); + +#ifdef __cplusplus +} +#endif diff --git a/16/xw_/modex/THREED.PAS b/16/xw_/modex/THREED.PAS new file mode 100755 index 00000000..8b712c9d --- /dev/null +++ b/16/xw_/modex/THREED.PAS @@ -0,0 +1,40 @@ +unit ThreeD; +interface + +type + TVector = record + X, Y, Z : longint; + end; + TPoint = TVector; + +function tdFixedMul( F1, F2: longint ): longint; +function tdGetSurfaceLight( var Normal: TPoint ): integer; +function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint; + +procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word ); +procedure tdGetNormal( var Dest, P1, P2, P3: TVector ); +procedure tdRotate( var Source, Dest; Count: word ); +procedure tdSetLight( var Light: TVector ); +procedure tdSetRotation( RX, RY, RZ: word ); +procedure tdSetTranslation( var TV: TVector ); +procedure tdSetPerspective( PD, XF, YF: longint ); +procedure tdTransform( var Source, Dest; Count: word ); +procedure tdTransformLight( var Source, Dest; Count: word ); + +implementation + +function tdGetSurfaceLight; external; +procedure tdSetRotation( RX, RY, RZ: word ); external; +procedure tdGetNormal; external; +procedure tdSetTranslation( var TV: TVector ); external; +procedure tdTransform( var Source, Dest; Count: word ); external; +procedure tdRotate; external; +function tdTransformToImage; external; +procedure tdSetLight( var Light: TVector ); external; +procedure tdSetPerspective; external; +procedure tdTransformLight; external; +function tdFixedMul( F1, F2: longint ): longint; external; +procedure tdBackPlaneCull; external; +{$L THREED} + +end. diff --git a/16/xw_/modex/demo01.c b/16/xw_/modex/demo01.c new file mode 100755 index 00000000..98086b62 --- /dev/null +++ b/16/xw_/modex/demo01.c @@ -0,0 +1,133 @@ +/* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*/ +#include ../../x/ + +#DEFINE MAX_SPRITE 100 + +/* Sprite structure */ +typedef struct { + int X, Y; /* Sprite coordinates */ + int DX,DY; /* Deltas for sprite movement */ + int W, H; /* Sprite width and height */ + unsigned char Image[16,16]; /* Sprite image data */ +} TSprite; + +/* RGB color structure */ +typedef struct { + R, G, B: byte; +} TRgb; +var + S : array[ 1..MAX_SPRITE ] of TSprite; /* An array of sprites */ + Palette: array[ byte ] of TRgb; /* Palette */ + Page : word; /* Page offset */ + I : word; + +/* Initializes a sprite structure */ +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X = Random( 320 ); /* Initialize position with random values */ + S.Y = Random( 240 ); + S.DX = Random( 7 )-3; /* Initialize speed with random values */ + S.DY = Random( 7 )-3; + S.W = 16; /* Size is fixed in this program */ + S.H = 16; + /* The image is a square with a hole inside */ + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +} + +/* Moves a sprite */ +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); /* Get new position */ + Inc( S.Y, S.DY ); + /* Check sprite position, change delta if needed */ + if( S.X > 320 ) then begin + S.X = 320; + S.DX = -S.DX; + } + if( S.X < -16 ) then begin + S.X = -16; + S.DX = -S.DX; + } + if( S.Y > 240 ) then begin + S.Y = 240; + S.DY = -S.DY; + } + if( S.Y < -16 ) then begin + S.Y = -16; + S.DY = -S.DY; + } + /* Draw the sprite, note the Page offset added to the */ + /* Y coordinate of the image */ + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +} + +void main() +{ + int i; + /* Initialize library */ + mxInit(); + + /* Enter graphics mode */ + mxSetMode( MX_320x240 ); + + /* Print initialization message */ + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + /* Initialize sprites */ + for(i=1;i<=MAX_SPRITE;i++) + sxInit( S[i] ); + + /* Draw background */ + for(i=1;i<=192;i++) + { + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + } + + /* Compute and set palette */ + for(i=1;i<= 192;Palette[i+63]) + { + short R = 0; + short G = 0; + short B = 0; + if( i < 64 ) + R = i shr 1+31 + else if( i < 128 ) + G = (i-64) shr 1+31 + else + B = (i-128) shr 1+31; + } + mxSetPalette( @Palette[64], 64, 192 ); + + /* Main loop */ + short Page = 240; + while(!kbhit()) + { + /* Set clip region to current page */ + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + /* Restore background */ + mxBitBlt( 0, 480, 320, 240, 0, Page ); + /* Draw sprites */ + for(i=1; i <= MAX_SPRITE; sxMove( S[i] )); + /* Print message */ + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + /* Flip page */ + mxStartLine( Page ); + Page = 240-Page; + /* Animate palette */ + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + } + + mxSetMode( MX_TEXT ); + mxTerm; + +} diff --git a/16/xw_/mxbb.asm b/16/xw_/mxbb.asm new file mode 100755 index 00000000..5598cd10 --- /dev/null +++ b/16/xw_/mxbb.asm @@ -0,0 +1,207 @@ + PUBLIC MXBITBLT + EXTRN SUBHORIZONTALLINEINFO:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXBITBLT: + push bp + mov bp,sp + sub sp,16H + push ds + push si + push es + push di + cmp word ptr 0cH[bp],0 + je L$2 + mov ax,word ptr 10H[bp] + and al,3 + mov dx,word ptr 8[bp] + and dl,3 + mov bx,offset L$10 + cmp al,dl + jne L$1 + mov bx,offset L$3 +L$1: + call bx +L$2: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +L$3: + mov bx,word ptr 8[bp] + mov ax,word ptr 6[bp] + mov cx,word ptr 0cH[bp] + call near ptr MX_TEXT:SUBHORIZONTALLINEINFO + mov byte ptr -14H[bp],al + mov byte ptr -16H[bp],ah + mov word ptr 0cH[bp],cx + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov es,ax + mov ax,word ptr 0eH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov si,word ptr 10H[bp] + shr si,1 + shr si,1 + add si,ax + mov dx,3ceH + mov ax,4105H + out dx,ax + cld + mov ah,byte ptr -14H[bp] + or ah,ah + je L$5 + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + dec ax + mov cx,word ptr 0aH[bp] + push si + push di +L$4: + movsb + add si,ax + add di,ax + dec cx + jne L$4 + pop di + pop si + inc si + inc di +L$5: + mov bx,word ptr 0cH[bp] + test bx,bx + je L$7 + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + sub ax,bx + mov dx,word ptr 0aH[bp] + push si + push di +L$6: + mov cx,bx + rep movsb + add si,ax + add di,ax + dec dx + jne L$6 + pop di + pop si + add si,bx + add di,bx +L$7: + mov ah,byte ptr -16H[bp] + or ah,ah + je L$9 + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + dec ax + mov cx,word ptr 0aH[bp] +L$8: + movsb + add si,ax + add di,ax + dec cx + jne L$8 +L$9: + mov dx,3ceH + mov ax,4005H + out dx,ax + ret +L$10: + mov cx,word ptr 0cH[bp] + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov si,6 +L$11: + mov word ptr -8[bp+si],bx + shr al,1 + adc bx,0 + dec si + dec si + jge L$11 + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov es,ax + mov ax,word ptr 0eH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov si,word ptr 10H[bp] + shr si,1 + shr si,1 + add si,ax + mov word ptr -0aH[bp],si + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 8[bp] + shr di,1 + shr di,1 + add di,ax + mov word ptr -0cH[bp],di + mov ax,word ptr 10H[bp] + and al,3 + mov byte ptr -10H[bp],al + mov cx,word ptr 8[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -12H[bp],al + cld + mov byte ptr -0eH[bp],4 + lea bx,-8[bp] +L$12: + cmp word ptr ss:[bx],0 + je L$15 + mov ah,byte ptr -12H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -10H[bp] + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 0aH[bp] + mov ax,word ptr cs:MX_BYTESPERLINE + sub ax,word ptr ss:[bx] +L$13: + mov cx,word ptr ss:[bx] + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + add si,ax + add di,ax + dec dx + jne L$13 + inc bx + inc bx + inc byte ptr -10H[bp] + and byte ptr -10H[bp],3 + jne L$14 + inc word ptr -0aH[bp] +L$14: + rol byte ptr -12H[bp],1 + adc word ptr -0cH[bp],0 + mov si,word ptr -0aH[bp] + mov di,word ptr -0cH[bp] + dec byte ptr -0eH[bp] + jne L$12 +L$15: + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxcc.asm b/16/xw_/mxcc.asm new file mode 100755 index 00000000..efe64f3f --- /dev/null +++ b/16/xw_/mxcc.asm @@ -0,0 +1,628 @@ + PUBLIC XSUBCLIPLINE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + or al,byte ptr [bx+si] +L$2: + DW offset L$3 + or al,byte ptr [bx+si] + DW offset L$4 + or word ptr [bx+si],ax + DW offset L$5 +; ???? + inc word ptr [bx+si] + add byte ptr [bp+si],cl + add byte ptr 0a00H[bx+si],al + add byte ptr 900H[bp],dl + add byte ptr -100H[si],ch + inc word ptr [bx+si] + add byte ptr ds:[0c000H],al + add byte ptr ds:[0ce00H],al + add byte ptr [di],al + add ah,bl + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + DB 0 +L$3: + DW offset MX_TEXT+0ecH + DW offset MX_TEXT+0eeH + DW offset MX_TEXT+0f1H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+0f4H + DW offset MX_TEXT+0f7H + DW offset MX_TEXT+104H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+111H + DW offset MX_TEXT+114H + DW offset MX_TEXT+121H +L$4: + DW offset MX_TEXT+132H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+135H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+13bH + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+148H + DW offset L$7 + DW offset L$10 + DW offset L$7 + DW offset L$11 +L$5: + DW offset L$14 + DW offset L$15 + DW offset L$7 + DW offset L$7 + DW offset L$16 + DW offset L$17 + DW offset L$7 + DW offset L$7 + DW offset L$18 + DW offset L$19 + DW offset L$22 + DW offset L$23 + DW offset L$24 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$25 + DW offset L$26 + DW offset L$27 + DW offset L$30 + DW offset L$7 + DW offset L$31 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$32 + DW offset L$7 + DW offset L$33 + DW offset L$36 + DW offset L$37 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$38 + DW offset L$39 + DW offset L$43 + DW offset L$44 + DW offset L$45 + DW offset L$7 + DW offset L$46 + DW offset L$47 + DW offset L$48 + DW offset L$51 + DW offset L$7 + DW offset L$52 + DW offset L$7 + DW offset L$53 + DW offset L$7 + DW offset L$54 + DW offset L$58 + DW offset L$59 + DW offset L$7 + DW offset L$7 + DW offset L$60 + DW offset L$61 +L$6: + clc + ret +L$7: + stc + ret + clc + ret + jmp near ptr L$67 + jmp near ptr L$68 + jmp near ptr L$70 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$6 + jmp near ptr L$70 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jge L$6 + jmp near ptr L$70 + jmp near ptr L$69 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jle L$6 + jmp near ptr L$69 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jle L$6 + jmp near ptr L$69 +L$8: + stc + ret +L$9: + clc + ret + jmp near ptr L$63 + call near ptr L$63 + jmp near ptr L$68 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$8 + jmp near ptr L$70 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$8 + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX2 + jle L$9 + jmp near ptr L$68 +L$10: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$8 + jmp near ptr L$69 +L$11: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$8 + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX2 + jle L$9 + jmp near ptr L$68 +L$12: + clc + ret +L$13: + stc + ret +L$14: + jmp near ptr L$64 +L$15: + call near ptr L$64 + jmp near ptr L$67 +L$16: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$13 + jmp near ptr L$70 +L$17: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$13 + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX1 + jge L$12 + jmp near ptr L$67 +L$18: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$13 + jmp near ptr L$69 +L$19: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$13 + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX1 + jge L$12 + jmp near ptr L$67 +L$20: + clc + ret +L$21: + stc + ret +L$22: + jmp near ptr L$66 +L$23: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jl L$21 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$20 + jmp near ptr L$70 +L$24: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jg L$21 + jmp near ptr L$68 +L$25: + call near ptr L$66 + jmp near ptr L$69 +L$26: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jl L$21 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jle L$20 + jmp near ptr L$69 +L$27: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jg L$21 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jle L$20 + jmp near ptr L$69 +L$28: + clc + ret +L$29: + stc + ret +L$30: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$28 + jmp near ptr L$66 +L$31: + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jl L$29 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jge L$28 + jmp near ptr L$63 +L$32: + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX1 + jl L$29 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jge L$28 + jmp near ptr L$63 +L$33: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$29 + call near ptr L$68 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$29 + cmp si,word ptr cs:MX_CLIPY2 + jle L$28 + jmp near ptr L$69 +L$34: + clc + ret +L$35: + stc + ret +L$36: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$37: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jl L$35 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jle L$34 + jmp near ptr L$64 +L$38: + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX2 + jg L$35 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$39: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jl L$35 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$35 + cmp si,word ptr cs:MX_CLIPY2 + jle L$40 + call near ptr L$69 +L$40: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$41: + clc + ret +L$42: + stc + ret +L$43: + jmp near ptr L$65 +L$44: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jl L$42 + jmp near ptr L$67 +L$45: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jg L$42 + jmp near ptr L$68 +L$46: + call near ptr L$65 + jmp near ptr L$70 +L$47: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jl L$42 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$42 + jmp near ptr L$70 +L$48: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jg L$42 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jge L$41 + jmp near ptr L$70 +L$49: + clc + ret +L$50: + stc + ret +L$51: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$49 + jmp near ptr L$65 +L$52: + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jg L$50 + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jge L$49 + jmp near ptr L$63 +L$53: + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX1 + jl L$50 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$49 + jmp near ptr L$65 +L$54: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$50 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jg L$50 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$55 + call near ptr L$65 +L$55: + cmp si,word ptr cs:MX_CLIPY1 + jge L$49 + jmp near ptr L$70 +L$56: + clc + ret +L$57: + stc + ret +L$58: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp near ptr L$65 +L$59: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jg L$57 + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jle L$56 + jmp L$64 +L$60: + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX2 + jg L$57 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp L$65 +L$61: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jg L$57 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$57 + cmp si,word ptr cs:MX_CLIPY1 + jge L$62 + call near ptr L$70 +L$62: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp L$65 +L$63: + mov ax,si + sub ax,bx + mov dx,word ptr cs:MX_CLIPX1 + sub dx,di + imul dx + mov bp,cx + sub bp,di + idiv bp + add bx,ax + mov di,word ptr cs:MX_CLIPX1 + clc + ret +L$64: + mov ax,si + sub ax,bx + mov dx,word ptr cs:MX_CLIPX2 + sub dx,di + imul dx + mov bp,cx + sub bp,di + idiv bp + add bx,ax + mov di,word ptr cs:MX_CLIPX2 + clc + ret +L$65: + mov ax,cx + sub ax,di + mov dx,word ptr cs:MX_CLIPY2 + sub dx,bx + imul dx + mov bp,si + sub bp,bx + idiv bp + add di,ax + mov bx,word ptr cs:MX_CLIPY2 + clc + ret +L$66: + mov ax,cx + sub ax,di + mov dx,word ptr cs:MX_CLIPY1 + sub dx,bx + imul dx + mov bp,si + sub bp,bx + idiv bp + add di,ax + mov bx,word ptr cs:MX_CLIPY1 + clc + ret +L$67: + mov ax,bx + sub ax,si + mov dx,word ptr cs:MX_CLIPX1 + sub dx,cx + imul dx + mov bp,di + sub bp,cx + idiv bp + add si,ax + mov cx,word ptr cs:MX_CLIPX1 + clc + ret +L$68: + mov ax,bx + sub ax,si + mov dx,word ptr cs:MX_CLIPX2 + sub dx,cx + imul dx + mov bp,di + sub bp,cx + idiv bp + add si,ax + mov cx,word ptr cs:MX_CLIPX2 + clc + ret +L$69: + mov ax,di + sub ax,cx + mov dx,word ptr cs:MX_CLIPY2 + sub dx,si + imul dx + mov bp,bx + sub bp,si + idiv bp + add cx,ax + mov si,word ptr cs:MX_CLIPY2 + clc + ret +L$70: + mov ax,di + sub ax,cx + mov dx,word ptr cs:MX_CLIPY1 + sub dx,si + imul dx + mov bp,bx + sub bp,si + idiv bp + add cx,ax + mov si,word ptr cs:MX_CLIPY1 + clc + ret +XSUBCLIPLINE: + push bp + xor si,si + cmp dx,word ptr cs:MX_CLIPY2 + jle L$71 + or si,8 + jmp L$72 +L$71: + cmp dx,word ptr cs:MX_CLIPY1 + jge L$72 + or si,4 +L$72: + cmp cx,word ptr cs:MX_CLIPX2 + jle L$73 + or si,2 + jmp L$74 +L$73: + cmp cx,word ptr cs:MX_CLIPX1 + jge L$74 + or si,1 +L$74: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$75 + or si,80H + jmp L$76 +L$75: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$76 + or si,40H +L$76: + cmp ax,word ptr cs:MX_CLIPX2 + jle L$77 + or si,20H + jmp L$78 +L$77: + cmp ax,word ptr cs:MX_CLIPX1 + jge L$78 + or si,10H +L$78: + mov di,si + and di,0fH + and si,0f0H + shr si,1 + shr si,1 + cmp di,word ptr cs:L$1[si] + jg L$79 + mov si,word ptr cs:L$2[si] + shl di,1 + add si,di + mov di,ax + mov si,word ptr cs:[si] + xchg si,dx + call dx + mov ax,di + mov dx,si + pop bp + ret +L$79: + pop bp + stc + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxcg.asm b/16/xw_/mxcg.asm new file mode 100755 index 00000000..c29a48ec --- /dev/null +++ b/16/xw_/mxcg.asm @@ -0,0 +1,42 @@ + PUBLIC MXCOLORTOGRAY +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXCOLORTOGRAY: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov cx,word ptr 6[bp] + jcxz L$2 + lds si,dword ptr 0cH[bp] + les di,dword ptr 8[bp] + cld + mov bx,4d97H +L$1: + lodsb + mul bh + mov dx,ax + lodsb + mul bl + add dx,ax + lodsb + mov ah,1cH + mul ah + add ax,dx + mov al,ah + stosw + stosb + loop L$1 +L$2: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0aH +MX_TEXT ENDS + END diff --git a/16/xw_/mxcl.asm b/16/xw_/mxcl.asm new file mode 100755 index 00000000..549bc8ce --- /dev/null +++ b/16/xw_/mxcl.asm @@ -0,0 +1,110 @@ + PUBLIC MXCIRCLE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXCIRCLE: + push bp + mov bp,sp + sub sp,2 + push ds + push si + push di + xor si,si + mov di,word ptr 8[bp] + mov ax,3 + sub ax,di + sub ax,di + mov word ptr -2[bp],ax + mov ds,word ptr cs:MX_VIDEOSEGMENT +L$1: + cmp si,di + jg L$3 + mov ax,si + mov bx,di + call near ptr L$4 + mov ax,si + neg ax + mov bx,di + call near ptr L$4 + mov ax,si + mov bx,di + neg bx + call near ptr L$4 + mov ax,si + neg ax + mov bx,di + neg bx + call near ptr L$4 + mov ax,di + mov bx,si + call near ptr L$4 + mov ax,di + neg ax + mov bx,si + call near ptr L$4 + mov ax,di + mov bx,si + neg bx + call near ptr L$4 + mov ax,di + neg ax + mov bx,si + neg bx + call near ptr L$4 + mov ax,word ptr -2[bp] + test ax,ax + jl L$2 + mov ax,di + shl ax,1 + shl ax,1 + sub ax,4 + sub word ptr -2[bp],ax + dec di +L$2: + mov ax,si + shl ax,1 + shl ax,1 + add ax,6 + add word ptr -2[bp],ax + inc si + jmp L$1 +L$3: + xor ax,ax + pop di + pop si + pop ds + mov sp,bp + pop bp + retf 8 +L$4: + add bx,word ptr 0cH[bp] + add ax,word ptr 0aH[bp] + cmp bx,word ptr cs:MX_CLIPX1 + jl L$5 + cmp bx,word ptr cs:MX_CLIPX2 + jg L$5 + cmp ax,word ptr cs:MX_CLIPY1 + jl L$5 + cmp ax,word ptr cs:MX_CLIPY2 + jg L$5 + mul word ptr cs:MX_BYTESPERLINE + mov cx,bx + shr bx,1 + shr bx,1 + add bx,ax + and cl,3 + mov ax,102H + shl ah,cl + mov dx,3c4H + out dx,ax + mov al,byte ptr 6[bp] + mov byte ptr [bx],al +L$5: + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxcr.asm b/16/xw_/mxcr.asm new file mode 100755 index 00000000..826e065a --- /dev/null +++ b/16/xw_/mxcr.asm @@ -0,0 +1,243 @@ + PUBLIC MX_CLIPX1 + PUBLIC MX_CLIPY1 + PUBLIC MX_CLIPX2 + PUBLIC MX_CLIPY2 + PUBLIC MXSETCLIP + PUBLIC MXGETCLIP + PUBLIC MXSETSYSCLIPREGION + PUBLIC MXSETCLIPREGION + PUBLIC MXGETCLIPREGION + PUBLIC SUBCLIPIMAGE + PUBLIC SUBCLIPBOX + EXTRN MX_CODESEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_CLIPX1: + add byte ptr [bx+si],al +MX_CLIPY1: + add byte ptr [bx+si],al +MX_CLIPX2: + add byte ptr [bx+si],al +MX_CLIPY2: + add byte ptr [bx+si],al +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +L$3: + add byte ptr [bx+si],al +L$4: + add byte ptr [bx+si],al +L$5: + add byte ptr [bx+si],al +L$6: + add byte ptr [bx+si],al +L$7: + add byte ptr [bx+si],al +L$8: + add byte ptr [bx+si],al +L$9: + DB 0 +MXSETCLIP: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr L$5 + mov bx,word ptr L$6 + mov cx,word ptr L$7 + mov dx,word ptr L$8 + cmp byte ptr 6[bp],1 + je L$10 + mov ax,word ptr L$1 + mov bx,word ptr L$2 + mov cx,word ptr L$3 + mov dx,word ptr L$4 +L$10: + mov word ptr MX_CLIPX1,ax + mov word ptr MX_CLIPY1,bx + mov word ptr MX_CLIPX2,cx + mov word ptr MX_CLIPY2,dx + mov al,byte ptr 6[bp] + xchg byte ptr L$9,al + xor ah,ah + pop ds + mov sp,bp + pop bp + retf 2 +MXGETCLIP: + mov al,byte ptr cs:L$9 + xor ah,ah + retf +MXSETSYSCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + xor ax,ax + mov word ptr L$1,ax + mov word ptr L$2,ax + mov ax,word ptr 8[bp] + dec ax + mov word ptr L$3,ax + mov ax,word ptr 6[bp] + dec ax + mov word ptr L$4,ax + mov ax,0 + push ax + push cs + call near ptr MXSETCLIP + pop ds + mov sp,bp + pop bp + retf 4 +MXSETCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 0cH[bp] + mov word ptr L$5,ax + mov ax,word ptr 0aH[bp] + mov word ptr L$6,ax + mov ax,word ptr 8[bp] + add ax,word ptr 0cH[bp] + dec ax + mov word ptr L$7,ax + mov ax,word ptr 6[bp] + add ax,word ptr 0aH[bp] + dec ax + mov word ptr L$8,ax + mov al,byte ptr L$9 + cmp al,1 + jne L$11 + push ax + push cs + call near ptr MXSETCLIP +L$11: + xor ax,ax + pop ds + mov sp,bp + pop bp + retf 8 +MXGETCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push es + push di + mov ax,word ptr cs:L$5 + les di,dword ptr 12H[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$6 + les di,dword ptr 0eH[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$7 + sub ax,word ptr cs:L$5 + inc ax + les di,dword ptr 0aH[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$8 + sub ax,word ptr cs:L$6 + inc ax + les di,dword ptr 6[bp] + mov word ptr es:[di],ax + mov al,byte ptr cs:L$9 + xor ah,ah + pop di + pop es + mov sp,bp + pop bp + retf 10H +SUBCLIPIMAGE: + xor si,si + mov di,word ptr cs:MX_CLIPY1 + cmp ax,di + jge L$12 + sub di,ax + sub dx,di + jle L$16 + mov ax,di + mov di,dx + mul cx + mov si,ax + mov dx,di + mov ax,word ptr cs:MX_CLIPY1 +L$12: + mov di,word ptr cs:MX_CLIPY2 + cmp ax,di + jg L$16 + inc di + sub di,dx + sub di,ax + jge L$13 + add dx,di +L$13: + mov di,word ptr cs:MX_CLIPX1 + cmp bx,di + jge L$14 + sub di,bx + sub cx,di + jle L$16 + add si,di + mov bx,word ptr cs:MX_CLIPX1 +L$14: + mov di,word ptr cs:MX_CLIPX2 + cmp bx,di + jg L$16 + inc di + sub di,bx + sub di,cx + jge L$15 + add cx,di +L$15: + clc + ret +L$16: + stc + ret +SUBCLIPBOX: + mov di,word ptr cs:MX_CLIPY1 + cmp ax,di + jge L$17 + sub di,ax + sub dx,di + jle L$21 + mov ax,word ptr cs:MX_CLIPY1 +L$17: + mov di,word ptr cs:MX_CLIPY2 + cmp ax,di + jg L$21 + inc di + sub di,dx + sub di,ax + jge L$18 + add dx,di +L$18: + mov di,word ptr cs:MX_CLIPX1 + cmp bx,di + jge L$19 + sub di,bx + sub cx,di + jle L$21 + mov bx,word ptr cs:MX_CLIPX1 +L$19: + mov di,word ptr cs:MX_CLIPX2 + cmp bx,di + jg L$21 + inc di + sub di,bx + sub di,cx + jge L$20 + add cx,di +L$20: + clc + ret +L$21: + stc + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxel.asm b/16/xw_/mxel.asm new file mode 100755 index 00000000..e69de29b diff --git a/16/xw_/mxfb.asm b/16/xw_/mxfb.asm new file mode 100755 index 00000000..e20f1dc9 --- /dev/null +++ b/16/xw_/mxfb.asm @@ -0,0 +1,133 @@ + PUBLIC MXFILLBOX + EXTRN SUBCLIPBOX:BYTE + EXTRN SUBHORIZONTALLINEINFO:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov ah,al + shr cx,1 + rep stosw + rcl cx,1 + rep stosb + ret +L$2: + mov byte ptr [bx],al + add bx,dx + loop L$2 + ret +L$3: + mov si,di +L$4: + mov ah,byte ptr [si] + mov byte ptr [si],al + inc si + loop L$4 + ret +L$5: + mov ah,byte ptr [bx] + mov byte ptr [bx],al + add bx,dx + loop L$5 + ret +MXFILLBOX: + push bp + mov bp,sp + sub sp,8 + push ds + push si + push es + push di + mov bx,word ptr 10H[bp] + mov ax,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + mov dx,word ptr 0aH[bp] + call near ptr MX_TEXT:SUBCLIPBOX + jae L$6 + jmp near ptr L$12 +L$6: + mov word ptr 0aH[bp],dx + call near ptr MX_TEXT:SUBHORIZONTALLINEINFO + mov word ptr 0cH[bp],cx + mov byte ptr -2[bp],al + mov byte ptr -4[bp],ah + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov es,ax + mov ds,ax + cld + mov word ptr -6[bp],offset L$2 + mov word ptr -8[bp],offset L$1 + mov ax,word ptr 6[bp] + cmp al,3 + ja L$7 + cmp al,0 + je L$7 + shl al,1 + shl al,1 + shl al,1 + mov ah,al + mov al,3 + mov dx,3ceH + out dx,ax + mov word ptr -6[bp],offset L$5 + mov word ptr -8[bp],offset L$3 +L$7: + mov ah,byte ptr -2[bp] + or ah,ah + je L$8 + mov dx,3c4H + mov al,2 + out dx,ax + mov dx,word ptr cs:MX_BYTESPERLINE + mov cx,word ptr 0aH[bp] + mov bx,di + mov al,byte ptr 8[bp] + call word ptr -6[bp] + inc di +L$8: + mov cx,word ptr 0cH[bp] + jcxz L$10 + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov al,byte ptr 8[bp] + mov bx,di + mov dx,word ptr 0aH[bp] + push di +L$9: + mov di,bx + call word ptr -8[bp] + mov cx,word ptr 0cH[bp] + add bx,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$9 + pop di + add di,word ptr 0cH[bp] +L$10: + mov ah,byte ptr -4[bp] + or ah,ah + je L$11 + mov dx,3c4H + mov al,2 + out dx,ax + mov dx,word ptr cs:MX_BYTESPERLINE + mov cx,word ptr 0aH[bp] + mov bx,di + mov al,byte ptr 8[bp] + call word ptr -6[bp] +L$11: + mov dx,3ceH + mov ax,3 + out dx,ax +L$12: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw_/mxfp.asm b/16/xw_/mxfp.asm new file mode 100755 index 00000000..7ff26176 --- /dev/null +++ b/16/xw_/mxfp.asm @@ -0,0 +1,219 @@ + PUBLIC MXFADEPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP + inc bx + outsw + jo L$5 + jb L$4 + push 2074H + sub byte ptr 29H[bp+di],ah + and byte ptr [bx+di],dh + cmp word ptr [bx+di],di + xor ch,byte ptr [di] + xor word ptr [bx+di],di + cmp word ptr [si],si + and byte ptr 52H[bx+di],al + push sp + dec cx + push bx + and byte ptr 2eH[bp+di],dh + jb L$1 + insb + and byte ptr cs:6cH[bx+di],al + insb + and byte ptr 69H[bp+si],dh + push 7374H + and byte ptr 65H[bp+si],dh + jae L$7 + jb L$9 + DB 65H, 64H, 2eH +MXFADEPALETTE: + push bp + mov bp,sp + sub sp,60aH + push si + push di + push ds + push es + mov word ptr -608H[bp],1 + mov ax,word ptr 10H[bp] + and ax,0ff00H +L$1: + je L$2 + mov cl,8 + shr ax,cl + mov word ptr -608H[bp],ax +L$2: + mov ax,word ptr 10H[bp] + and ax,0feH + mov cl,1 + shr ax,cl + or ax,ax + jne L$3 + mov ax,30H +L$3: + mov word ptr -60aH[bp],ax +L$4: + inc ax + mov byte ptr -606H[bp],al + mov byte ptr -604H[bp],1 + DB 0c6H, 86H, 0feH, 0f9H +L$5: + add byte ptr 0e46H[bp+di],cl + cmp ax,100H + jb L$6 + jmp near ptr L$12 +L$6: + add ax,word ptr 0cH[bp] + cmp ax,100H + jbe L$8 + mov ax,100H + sub ax,word ptr 0eH[bp] + DB 89H, 46H +L$7: + or al,0bH + ???? + jne L$8 + jmp near ptr L$12 +L$8: + mov cx,word ptr 0cH[bp] + mov ax,cx + shl ax,1 + add cx,ax + mov ax,ss +L$9: + mov es,ax + lea di,-300H[bp] + mov ax,word ptr 0eH[bp] + mov si,ax + shl ax,1 + add ax,si + lds si,dword ptr 12H[bp] + add si,ax + cld + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + test word ptr 10H[bp],1 + je L$10 + mov ax,word ptr -60aH[bp] + mov byte ptr -602H[bp],al + mov byte ptr -604H[bp],0ffH + mov ax,ss + mov ds,ax + mov es,ax + lea di,-300H[bp] + mov ax,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + call near ptr L$19 +L$10: + mov bh,byte ptr 0aH[bp] + and bh,3fH + mov bl,byte ptr 8[bp] + and bl,3fH + mov dh,byte ptr 6[bp] + and dh,3fH + mov dl,byte ptr -602H[bp] + mov ax,ss + mov ds,ax + mov es,ax +L$11: + mov ax,word ptr 0cH[bp] + mov cx,word ptr -60aH[bp] + lea si,-300H[bp] + lea di,-600H[bp] + call near ptr L$13 + push bx + push dx + lea si,-600H[bp] + mov ax,word ptr 0eH[bp] + mov bx,word ptr 0cH[bp] + mov cx,word ptr -608H[bp] + call near ptr L$15 + pop dx + pop bx + add dl,byte ptr -604H[bp] + dec byte ptr -606H[bp] + jne L$11 +L$12: + pop es + pop ds + pop di + pop si + mov sp,bp + pop bp + retf 10H +L$13: + cld + push bp + mov bp,ax +L$14: + lodsb + sub al,bh + imul dl + idiv cl + add al,bh + stosb + lodsb + sub al,bl + imul dl + idiv cl + add al,bl + stosb + lodsb + sub al,dh + imul dl + idiv cl + add al,dh + stosb + dec bp + jne L$14 + pop bp + ret +L$15: + mov ah,al + mov dx,3daH +L$16: + in al,dx + test al,8 + jne L$16 +L$17: + in al,dx + test al,8 + je L$17 + loop L$16 + mov cx,bx + mov dx,3c8H + mov al,ah + out dx,al + inc dx + cld + cli +L$18: + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + loop L$18 + sti + ret +L$19: + mov dx,3c7H + out dx,al + inc dx + inc dx + cld +L$20: + in al,dx + stosb + in al,dx + stosb + in al,dx + stosb + loop L$20 + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxgc.asm b/16/xw_/mxgc.asm new file mode 100755 index 00000000..2f297632 --- /dev/null +++ b/16/xw_/mxgc.asm @@ -0,0 +1,30 @@ + PUBLIC MXGETCOLOR +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr 12H[bp] + mov dx,3c7H + out dx,al + inc dx + inc dx + lds si,dword ptr 0eH[bp] + in al,dx + mov byte ptr [si],al + lds si,dword ptr 0aH[bp] + in al,dx + mov byte ptr [si],al + lds si,dword ptr 6[bp] + in al,dx + mov byte ptr [si],al + pop si + pop ds + mov sp,bp + pop bp + retf 0eH +MX_TEXT ENDS + END diff --git a/16/xw_/mxgi.asm b/16/xw_/mxgi.asm new file mode 100755 index 00000000..0570d498 --- /dev/null +++ b/16/xw_/mxgi.asm @@ -0,0 +1,98 @@ + PUBLIC MXGETIMAGE + EXTRN SUBCLIPIMAGE:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETIMAGE: + push bp + mov bp,sp + sub sp,10H + push ds + push si + push es + push di + mov bx,word ptr 0cH[bp] + mov ax,word ptr 0aH[bp] + mov cx,word ptr 8[bp] + mov dx,word ptr 6[bp] + call near ptr MX_TEXT:SUBCLIPIMAGE + jae L$1 + jmp near ptr L$7 +L$1: + mov word ptr 6[bp],dx + add word ptr 0eH[bp],si + mul word ptr cs:MX_BYTESPERLINE + mov si,bx + shr si,1 + shr si,1 + add si,ax + mov word ptr -0aH[bp],si + mov ds,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -0eH[bp],bl + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov di,6 +L$2: + mov word ptr -8[bp+di],bx + shr al,1 + adc bx,0 + dec di + dec di + jge L$2 + cld + mov byte ptr -10H[bp],4 + lea bx,-8[bp] + mov es,word ptr 10H[bp] + mov ah,byte ptr -0eH[bp] +L$3: + cmp word ptr ss:[bx],0 + je L$7 + mov di,word ptr 0eH[bp] + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 6[bp] + mov si,word ptr -0aH[bp] +L$4: + push si + push di + mov cx,word ptr ss:[bx] +L$5: + movsb + add di,3 + dec cx + jne L$5 + pop di + pop si + add di,word ptr 8[bp] + add si,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$4 + inc bx + inc bx + inc ah + test ah,4 + je L$6 + inc word ptr -0aH[bp] + and ah,3 +L$6: + inc word ptr 0eH[bp] + dec byte ptr -10H[bp] + jne L$3 +L$7: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw_/mxgm.asm b/16/xw_/mxgm.asm new file mode 100755 index 00000000..8ca07a17 --- /dev/null +++ b/16/xw_/mxgm.asm @@ -0,0 +1,68 @@ + PUBLIC MXGAMMACORRECT +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bp+si],cl + push cs + adc word ptr [bp+di],dx + adc ax,1817H + sbb bl,byte ptr [bp+di] + sbb al,1dH + pop ds + and byte ptr [bx+di],ah + and ah,byte ptr [bp+di] + and al,25H + and ax,2726H + sub byte ptr [bx+di],ch + sub word ptr [bp+si],bp + sub bp,word ptr [si] + sub al,2dH + das + xor byte ptr [bx+si],dh + xor word ptr [bx+di],si + xor dh,byte ptr [bp+di] + xor si,word ptr [si] + xor al,35H + xor ax,3636H + aaa + aaa + cmp byte ptr [bx+si],bh + cmp word ptr [bx+di],di + cmp bh,byte ptr [bp+si] + cmp di,word ptr [bp+di] + cmp al,3cH + cmp ax,3e3dH + aas + aas +MXGAMMACORRECT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov cx,word ptr 6[bp] + jcxz L$3 + lds si,dword ptr 0cH[bp] + les di,dword ptr 8[bp] + mov bx,offset L$1 + cld + mov ax,cx + add cx,cx + add cx,ax +L$2: + lodsb + xlat word ptr cs:[bx] + stosb + loop L$2 +L$3: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0aH +MX_TEXT ENDS + END diff --git a/16/xw_/mxgp.asm b/16/xw_/mxgp.asm new file mode 100755 index 00000000..14dfc17a --- /dev/null +++ b/16/xw_/mxgp.asm @@ -0,0 +1,32 @@ + PUBLIC MXGETPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETPALETTE: + push bp + mov bp,sp + sub sp,0 + push es + push di + les di,dword ptr 0aH[bp] + mov cx,word ptr 6[bp] + mov ax,word ptr 8[bp] + mov dx,3c7H + out dx,al + inc dx + inc dx + cld +L$1: + in al,dx + stosb + in al,dx + stosb + in al,dx + stosb + loop L$1 + pop di + pop es + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxgv.asm b/16/xw_/mxgv.asm new file mode 100755 index 00000000..44b30ddb --- /dev/null +++ b/16/xw_/mxgv.asm @@ -0,0 +1,8 @@ + PUBLIC MXGETVERSION +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETVERSION: + mov ax,128H + retf +MX_TEXT ENDS + END diff --git a/16/xw_/mxhl.asm b/16/xw_/mxhl.asm new file mode 100755 index 00000000..f664632b --- /dev/null +++ b/16/xw_/mxhl.asm @@ -0,0 +1,45 @@ + PUBLIC SUBHORIZONTALLINEINFO + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bx+si],al + add ax,word ptr [bx+si] + add al,byte ptr [bx+si] + add word ptr [bx+si],ax +L$2: + add byte ptr ds:[80cH],cl +L$3: + add byte ptr [bx+di],al + add ax,word ptr [bx] +L$4: + DB 2, 6 +SUBHORIZONTALLINEINFO: + ;DD ds:[63278] + ASSUME ds:NOTHING + add byte ptr -2e05H[bp+di],cl + out dx,ax + shr di,1 + add di,ax + and bx,3 + mov al,byte ptr cs:L$2[bx] + shl bx,1 + sub cx,word ptr cs:L$1[bx] + jge L$5 + mov bx,cx + inc bx + inc bx + and al,byte ptr cs:L$4[bx] + xor ah,ah + xor cx,cx + jmp L$6 +L$5: + mov bx,cx + and bx,3 + mov ah,byte ptr cs:L$3[bx] + shr cx,1 + shr cx,1 +L$6: + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxit.asm b/16/xw_/mxit.asm new file mode 100755 index 00000000..25bce3c3 --- /dev/null +++ b/16/xw_/mxit.asm @@ -0,0 +1,98 @@ +;----------------------------------------------------------- +; +; MXIT.ASM - Initialization/termination functions +; Copyright (c) 1993,1994 by Alessandro Scotti +; +;----------------------------------------------------------- +;WARN PRO +INCLUDE MODEX.DEF + +PUBLIC mxInit +PUBLIC mxTerm + +PUBLIC mx_VideoSegment +PUBLIC mx_CodeSegment + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +DB 'MODEX library - Copyright (c) 1992-1994 Alessandro Scotti' + +mx_VideoSegment DW 0A000h +mx_CodeSegment DW SEG MX_TEXT + +;----------------------------------------------------------- +; +; Initialization. +; +; Input: +; none +; Output: +; AX = 0 on success +; +mxInit PROC FAR + LOCAL Result:WORD, \ + VideoSeg:WORD, \ + CStoDSalias:WORD = AUTO_SIZE + ASSUME ds:NOTHING + .enter AUTO_SIZE + .push ds, si, es, di + + mov [Result], -1 ; Assume an error + mov [VideoSeg], 0A000h ; Real mode video segment + mov [CStoDSalias], cs ; Real mode data alias for CS + +; Check if running in protected mode under DPMI + mov ax, 1686h + int 2Fh + or ax, ax + jnz @@1 ; DPMI not found, continue in real mode + +; Get a data alias for CS + mov ax, 000Ah ; DMPI: create data alias + mov bx, cs + int 31h + jc @@Exit ; Exit if service failed + mov [CStoDSalias], ax ; Save data alias for CS +; Get a protected-mode selector for the video segment + mov ax, 0002h + mov bx, 0A000h ; Real mode segment of video + int 31h ; DPMI: get segment selector + jc @@Exit ; Exit if service failed + mov [VideoSeg], ax ; Save protected mode video selector + +; Initialize variables +@@1: + mov ds, [CStoDSalias] + ASSUME ds:MX_TEXT + mov [mx_CodeSegment], ds + mov ax, [VideoSeg] + mov [mx_VideoSegment], ax + +; Don't bother with VGA check for now... + + mov [Result], 0 + +@@Exit: + mov ax, [Result] + .pop ds, si, es, di +; .leave +mxInit ENDP + +;----------------------------------------------------------- +; +; Termination. +; +; Input: +; none +; Output: +; always 0. +; +mxTerm PROC FAR + ASSUME ds:NOTHING + xor ax, ax + ret +mxTerm ENDP + +MX_TEXT ENDS +END diff --git a/16/xw_/mxll.asm b/16/xw_/mxll.asm new file mode 100755 index 00000000..f08de8d4 --- /dev/null +++ b/16/xw_/mxll.asm @@ -0,0 +1,50 @@ + PUBLIC MXLOADLATCHES + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXLOADLATCHES: + push ds + push si + mov dx,3ceH + mov ax,0ff08H + out dx,ax + mov ax,3 + out dx,ax + mov ax,5 + out dx,ax + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov si,0ffffH + mov bh,8 + mov cx,3 +L$1: + mov dx,3ceH + mov al,4 + mov ah,cl + out dx,ax + mov dx,3c4H + mov al,2 + mov ah,bh + out dx,ax + mov al,byte ptr [si] + push ax + mov byte ptr [si],bl + mov al,byte ptr [di] + shr bh,1 + loop L$1 + mov cx,3 + mov bh,8 + mov dx,3c4H +L$2: + mov al,2 + mov ah,bh + out dx,ax + pop ax + mov byte ptr [si],al + shr bh,1 + loop L$2 + pop si + pop ds + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxln.asm b/16/xw_/mxln.asm new file mode 100755 index 00000000..77d2b64b --- /dev/null +++ b/16/xw_/mxln.asm @@ -0,0 +1,332 @@ + PUBLIC MXLINE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$29 + DW offset L$32 + DW offset L$35 + DW offset L$38 +MXLINE: + push bp + mov bp,sp + sub sp,12H + push ds + push si + push di + mov ax,word ptr 10H[bp] + mov bx,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + mov dx,word ptr 0aH[bp] + call near ptr L$8 + jae L$2 + jmp near ptr L$7 +L$2: + mov si,cx + xchg ax,si + sub ax,si + jge L$3 + xchg cx,si + xchg dx,bx + neg ax +L$3: + mov word ptr -2[bp],ax + mov cx,word ptr cs:MX_BYTESPERLINE + mov ax,dx + sub ax,bx + jge L$4 + neg cx + neg ax +L$4: + mov word ptr -4[bp],ax + mov word ptr -0cH[bp],cx + mov ax,bx + mul word ptr cs:MX_BYTESPERLINE + mov cx,si + shr si,1 + shr si,1 + add si,ax + and cl,3 + mov ax,1102H + shl ah,cl + mov byte ptr -12H[bp],ah + mov dx,3c4H + out dx,ax + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + xor bx,bx + mov al,byte ptr 6[bp] + cmp al,0 + je L$5 + and al,3 + shl al,1 + shl al,1 + shl al,1 + mov ah,al + mov al,3 + mov dx,3ceH + out dx,ax + inc bx + inc bx +L$5: + mov ax,word ptr -2[bp] + mov cx,word ptr -4[bp] + cmp ax,cx + jae L$6 + inc bx +L$6: + shl bx,1 + call word ptr cs:L$1[bx] + cmp byte ptr 6[bp],0 + je L$7 + mov ax,3 + mov dx,3ceH + out dx,ax +L$7: + xor ax,ax + pop di + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +L$8: + mov di,ax + mov si,dx + xor al,al + cmp cx,word ptr cs:MX_CLIPX1 + jge L$9 + or al,1 +L$9: + cmp cx,word ptr cs:MX_CLIPX2 + jle L$10 + or al,2 +L$10: + cmp si,word ptr cs:MX_CLIPY1 + jge L$11 + or al,4 +L$11: + cmp si,word ptr cs:MX_CLIPY2 + jle L$12 + or al,8 +L$12: + mov byte ptr -10H[bp],al + xor al,al + cmp di,word ptr cs:MX_CLIPX1 + jge L$13 + or al,1 +L$13: + cmp di,word ptr cs:MX_CLIPX2 + jle L$14 + or al,2 +L$14: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$15 + or al,4 +L$15: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$16 + or al,8 +L$16: + mov byte ptr -0eH[bp],al + mov ah,byte ptr -10H[bp] + test ah,al + je L$17 + jmp near ptr L$28 +L$17: + or ah,al + jne L$18 + jmp near ptr L$27 +L$18: + mov ax,cx + sub ax,di + mov word ptr -0aH[bp],ax + mov ax,si + sub ax,bx + mov word ptr -0cH[bp],ax + mov al,byte ptr -0eH[bp] +L$19: + test al,al + jne L$20 + xchg di,cx + xchg si,bx + xchg byte ptr -10H[bp],al +L$20: + test al,1 + je L$21 + mov ax,word ptr cs:MX_CLIPX1 + sub ax,di + mov di,word ptr cs:MX_CLIPX1 + jmp L$22 +L$21: + test al,2 + je L$23 + mov ax,word ptr cs:MX_CLIPX2 + sub ax,di + mov di,word ptr cs:MX_CLIPX2 +L$22: + imul word ptr -0cH[bp] + idiv word ptr -0aH[bp] + add bx,ax + mov al,8 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$26 + mov al,4 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$26 + xor al,al + jmp L$26 +L$23: + test al,4 + je L$24 + mov ax,word ptr cs:MX_CLIPY1 + sub ax,bx + mov bx,word ptr cs:MX_CLIPY1 + jmp L$25 +L$24: + mov ax,word ptr cs:MX_CLIPY2 + sub ax,bx + mov bx,word ptr cs:MX_CLIPY2 +L$25: + imul word ptr -0aH[bp] + idiv word ptr -0cH[bp] + add di,ax + mov al,1 + cmp di,word ptr cs:MX_CLIPX1 + jl L$26 + mov al,2 + cmp di,word ptr cs:MX_CLIPX2 + jg L$26 + xor al,al +L$26: + mov ah,byte ptr -10H[bp] + test ah,al + jne L$28 + or ah,al + je L$27 + jmp near ptr L$19 +L$27: + mov ax,di + mov dx,si + clc + ret +L$28: + stc + ret +L$29: + mov di,ax + neg di + shl cx,1 + mov word ptr -6[bp],cx + mov cx,ax + shl ax,1 + mov word ptr -8[bp],ax + mov al,2 + mov ah,byte ptr -12H[bp] + mov bl,byte ptr 8[bp] + mov dx,3c4H + inc cx +L$30: + mov byte ptr [si],bl + dec cx + je L$31 + rol ah,1 + adc si,0 + out dx,ax + add di,word ptr -6[bp] + jl L$30 + add si,word ptr -0cH[bp] + sub di,word ptr -8[bp] + jmp L$30 +L$31: + ret +L$32: + mov di,cx + neg di + shl ax,1 + mov word ptr -6[bp],ax + mov ax,cx + shl ax,1 + mov word ptr -8[bp],ax + mov bl,byte ptr 8[bp] + mov ah,byte ptr -12H[bp] + mov al,2 + mov dx,3c4H + inc cx +L$33: + mov byte ptr [si],bl + dec cx + je L$34 + add si,word ptr -0cH[bp] + add di,word ptr -6[bp] + jl L$33 + rol ah,1 + adc si,0 + out dx,ax + sub di,word ptr -8[bp] + jmp L$33 +L$34: + ret +L$35: + mov di,ax + neg di + shl cx,1 + mov word ptr -6[bp],cx + mov cx,ax + shl ax,1 + mov word ptr -8[bp],ax + mov al,2 + mov ah,byte ptr -12H[bp] + mov bl,byte ptr 8[bp] + mov dx,3c4H + inc cx +L$36: + mov bh,byte ptr [si] + mov byte ptr [si],bl + dec cx + je L$37 + rol ah,1 + adc si,0 + out dx,ax + add di,word ptr -6[bp] + jl L$36 + add si,word ptr -0cH[bp] + sub di,word ptr -8[bp] + jmp L$36 +L$37: + ret +L$38: + mov di,cx + neg di + shl ax,1 + mov word ptr -6[bp],ax + mov ax,cx + shl ax,1 + mov word ptr -8[bp],ax + mov bl,byte ptr 8[bp] + mov ah,byte ptr -12H[bp] + mov al,2 + mov dx,3c4H + inc cx +L$39: + mov bh,byte ptr [si] + mov byte ptr [si],bl + dec cx + je L$40 + add si,word ptr -0cH[bp] + add di,word ptr -6[bp] + jl L$39 + rol ah,1 + adc si,0 + out dx,ax + sub di,word ptr -8[bp] + jmp L$39 +L$40: + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxot.asm b/16/xw_/mxot.asm new file mode 100755 index 00000000..f7e6fde4 --- /dev/null +++ b/16/xw_/mxot.asm @@ -0,0 +1,1330 @@ + PUBLIC MXSETFONT + PUBLIC MXSETTEXTCOLOR + PUBLIC MXOUTCHAR + PUBLIC MXOUTTEXT + PUBLIC MXSETTEXTSTEP + PUBLIC MXGETTEXTSTEP + EXTRN MX_CODESEGMENT:BYTE + EXTRN MXPUTIMAGE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +; Default 8x8 font +fnt_Default LABEL BYTE + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW 0 ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +L$1: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ; The label referred to here is an undefined location + ;;;;ffff + ;jle 0xff8bh + movsw + and word ptr -7e67H[di],7e7eH + call bx + call bx + out 0ffH,ax + jle L$9 +; ;???? +; ;???? +; ;???? + jl L$7 + adc byte ptr [bx+si],al + adc byte ptr [bx+si],bh +L$2: + jl L$2 + jl L$8 + adc byte ptr [bx+si],al + adc byte ptr [bx+si],bh + adc byte ptr -2[si],dl + push sp + adc dh,bh + adc byte ptr [bx+si],bh +L$3: + jl L$3 +L$4: + ;???? + jl L$5 + inc byte ptr [bx+si] + sbb byte ptr [si],bh + jle L$11 + cmp al,18H + add bh,bh + out 0c3H,ax + DB 81H, 81H, 0c3H, 0e7H +L$5: + inc word ptr [bx+si] + cmp al,66H + inc dx + inc dx + DB 66H, 3cH +L$6: + add bh,bh + ret + cwd + mov bp,99bdH +L$7: + ret + inc word ptr [bx] + add ax,word ptr [di] + ; The label referred to here is an undefined location + ;;;;;0ffff + ;;;;;js 0ffffffe1H + DB 84H +L$8: + test byte ptr 7cH[bx+si],bh + add byte ptr 7c82H[bp+si],10H + cmp byte ptr [bx+si],dl + sbb al,10H + sbb al,10H + adc byte ptr [bx+si],dl + xor byte ptr [bx+si],dh + and bh,byte ptr ds:[2222H] + ;;;;;pushad + cwd + pop dx + cmp al,0e7H + out 3cH,ax + pop dx + cwd + add byte ptr [bx+si],dl + xor byte ptr -10H[bx+si],dh +L$9: + jo L$10 + adc byte ptr [bx+si],al + add al,0e0H + ;;;;lock loopnz L$6 + adc byte ptr [bx+si],38H + push sp + adc byte ptr [bx+si],dl + push sp + cmp byte ptr [bx+si],dl + dec ax + dec ax + dec ax + dec ax + dec ax + add byte ptr [bx+si],cl + jle L$4 + xchg ax,dx + jb L$10 + adc dl,byte ptr [bp+si] + add byte ptr [si],bh + and bl,byte ptr [bx+si] + and al,24H + sbb byte ptr 3cH[si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + DB 0, 3eH + ;;;;DD ds:[03eh] +L$10: + add byte ptr [bx+si],bh + push sp + DB 10H +L$11: + adc byte ptr [bx+si],dl + push sp + cmp dh,bh + add byte ptr [bx+si],dl + cmp byte ptr 10H[si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr 38H[si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],cl + add al,0feH + add al,8 + add byte ptr [bx+si],al + add byte ptr [bx+si],ah + inc ax + inc byte ptr 20H[bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr -380H[bx+si],0 + add byte ptr [bx+si],al + and al,42H + inc word ptr 24H[bp+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],bh +L$12: + jl L$12 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ;???? + jl L$15 + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],dl + add byte ptr [bx+si],al + and al,24H + add byte ptr [bx+si],al + DB 0 +L$13: + add byte ptr [bx+si],al + and al,24H + ;;;;jle 140H + ;;;;jle 142H +L$14: + and al,0 + cmp byte ptr 50H[si],dl + cmp byte ptr [si],dl + push sp + cmp byte ptr [bx+si],dl + add byte ptr [bp+si],al + inc sp + or byte ptr [bx+si],dl + and byte ptr [bp+si],al + cmp byte ptr 38H[si],al + ;;;;pusha + xchg ax,sp +L$15: + DB 88H +L$16: + ;;;;je 138H + and byte ptr [bx+si],ah + inc ax + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + and byte ptr 40H[bx+si],al + inc ax + and byte ptr [bx+si],dl + add byte ptr 20H[bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],ah +L$17: + inc ax + add byte ptr [bx+si],al + and al,18H + jle L$18 + and al,0 + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + jl L$18 + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + and byte ptr [bx+si],al + add byte ptr [bx+si],al + cld + DB 0 +L$18: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + add byte ptr [bx+si],al + add al,8 + adc byte ptr [bx+si],ah + inc ax +L$19: + add byte ptr [bx+si],7cH + ;???? + DB 8aH, 92H +L$20: + mov byte ptr tbl_SystemFont[bx+2],al + DD L$21 +L$21: + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],bh + add byte ptr L$13[bx+si],bh + add al,18H + ;;;;pusha + cmp ah,0 + js L$14 + add al,38H + add al,84H + js L$22 +L$22: + sbb al,24H + inc sp + test dh,bh + add al,0eH + add ah,bh + cmp al,4 + add al,84H + js L$23 +L$23: + js L$16 + cmp al,84H + test byte ptr [bx+si],bh + cld + add al,4 + or byte ptr [bx+si],dl + and byte ptr [bx+si],ah + add byte ptr -7cH[bx+si],bh + test byte ptr -7cH[bx+si],bh + test byte ptr [bx+si],bh + js L$17 + test byte ptr 4[si],bh + test byte ptr [bx+si],bh + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],dl + adc byte ptr [bx+si],ah + or byte ptr [bx+si],dl + and byte ptr 20H[bx+si],al + adc byte ptr [bx+si],cl + add byte ptr [bx+si],al + add ah,bh + add byte ptr [bx+si],al + cld + add byte ptr [bx+si],al + inc ax + and byte ptr [bx+si],dl + or byte ptr [bx+si],dl + and byte ptr [bx+si],al + js L$19 + add al,8 + adc byte ptr [bx+si],al +L$24: + adc byte ptr [bx+si],al + jl L$20 + mov dx,0bea6H + cmp byte ptr [si],78H + test byte ptr -7b04H[si],al + test byte ptr -800H[si],al + test byte ptr -7b08H[si],al + test al,bh + add byte ptr -7cH[bx+si],bh + add byte ptr -7b80H[bx+si],78H + add al,dh + mov byte ptr -7b7cH[si],al + mov al,dh + add ah,bh + add byte ptr -7f10H[bx+si],80H + cld + add ah,bh + add byte ptr -7f10H[bx+si],80H + add byte ptr [bx+si],78H + test byte ptr -7b64H[bx+si],al + test byte ptr [bx+si],bh + test byte ptr -37cH[si],al + test byte ptr 84H[si],al + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + cmp byte ptr [bx+si],al + sbb al,8 + or byte ptr [bx+si],cl + mov byte ptr 70H[bx+si],cl + test byte ptr -1f70H[bx+si],cl + nop + mov byte ptr -8000H[si],al + add byte ptr -7f80H[bx+si],80H + cld + add dh,al + stosb + xchg ax,dx + add byte ptr -7d7eH[bp+si],0 + add dl,0a2H + xchg ax,dx + mov al,byte ptr 82H[bp] + js L$24 + test byte ptr -7b7cH[si],al + js L$25 +L$25: + clc + test byte ptr -7f08H[si],al + add byte ptr 7800H[bx+si],84H + test byte ptr -776cH[si],al + jbe L$26 +L$26: + clc + test byte ptr -6f08H[si],al + mov byte ptr 7800H[si],al + test byte ptr 478H[bx+si],al + test byte ptr [bx+si],bh + ;???? + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr -7b7cH[si],al + test byte ptr 7884H[si],al + add byte ptr -7b7cH[si],al + test byte ptr 3048H[si],al + add byte ptr -7d7eH[bp+si],al + adc byte ptr -3956H[bp+si],0 + add byte ptr 28H[si],10H + sub byte ptr -7eH[si],al + add byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add dh,bh + add al,8 + adc byte ptr [bx+si],ah + inc ax + inc byte ptr [bx+si] + js L$32 + inc ax + inc ax + inc ax + inc ax + js L$27 +L$27: + add byte ptr 2040H[bx+si],al + adc byte ptr [bx+si],cl + add al,0 + js L$29 + or byte ptr [bx+si],cl + or byte ptr [bx+si],cl + js L$28 +L$28: + adc byte ptr [bx+si],ch +L$29: + inc sp + add byte ptr [bx+si],0 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + and byte ptr [bx+si],ah + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp byte ptr [si],al + cmp al,44H + jl L$30 +L$30: + add byte ptr 40H[bx+si],al + js L$33 + inc sp + js L$31 +L$31: + add byte ptr [bx+si],al +L$32: + cmp al,40H + inc ax + inc ax + cmp al,0 + add byte ptr [si],al + add al,3cH + inc sp + inc sp + cmp al,0 + add byte ptr [bx+si],al + cmp byte ptr 7cH[si],al + inc ax + cmp al,0 + add byte ptr [si],cl + adc byte ptr [si],bh + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,44H + inc sp + cmp al,4 + cmp byte ptr [bx+si],al + inc ax + inc ax + js L$35 + inc sp + inc sp + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + add al,0 + add al,4 + add al,44H + cmp byte ptr [bx+si],al +L$33: + inc ax + inc ax + push ax + ;;;;pusha + push ax + dec ax + add byte ptr [bx+si],al + xor byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + add byte ptr 54H[bx+si],ch + push sp + inc sp + inc sp + add byte ptr [bx+si],al + add byte ptr 44H[bx+si],bh + inc sp + inc sp + inc sp + add byte ptr [bx+si],al + add byte ptr [bx+si],bh + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al +L$34: + js L$42 + inc sp + js L$41 + inc ax + DB 0 +L$35: + add byte ptr [si],bh + inc sp + inc sp + cmp al,4 + add al,0 + add byte ptr 60H[si],bl + inc ax + inc ax + inc ax + add byte ptr [bx+si],al + add byte ptr [bx+si],bh +L$36: + inc ax + jl L$38 + jl L$37 +L$37: + add byte ptr [bx+si],dl +L$38: + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + sub byte ptr [bx+si],dl + add byte ptr [bx+si],al + add byte ptr 44H[si],al +L$39: + push sp + push sp + ;;;;insb + add byte ptr [bx+si],al + add byte ptr 28H[si],al +L$40: + adc byte ptr [bx+si],ch + inc sp +L$41: + DB 0 +L$42: + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp al,4 + jl L$43 +L$43: + add byte ptr 4[si],bh + cmp byte ptr 7cH[bx+si],al + add byte ptr [bx+si],al + or byte ptr [bx+si],dl + adc byte ptr [bx+si],dh + adc byte ptr [bx+si],dl + or byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + and byte ptr [bx+si],dl + adc byte ptr [bx+si],bl + adc byte ptr [bx+si],dl + and byte ptr -68H[si],ah + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + sub byte ptr -7eH[si],al + cmp dh,0 + jl L$34 + add byte ptr 7c80H[bx+si],4 + jl L$44 +L$44: + sub byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + cmp al,0 + jl L$54 + jl L$53 + jl L$45 +L$45: + jle L$36 + cmp byte ptr [si],al + cmp al,44H + jl L$46 +L$46: + and al,0 +L$47: + cmp byte ptr [si],al + cmp al,44H + jl L$48 +L$48: + js L$49 +L$49: + cmp byte ptr [si],al + cmp al,44H + jl L$50 +L$50: + sbb byte ptr [bx+si],bl + cmp byte ptr [si],al + cmp al,44H + jl L$51 +L$51: + add byte ptr [bx+si],al + js L$39 + cmp byte ptr 8[bx+si],38H + jl L$40 + cmp byte ptr 7cH[si],al + inc ax + cmp al,0 + dec ax + add byte ptr [bx+si],bh + inc sp + jl L$55 + cmp al,0 + js L$52 +L$52: + cmp byte ptr 7cH[si],al + inc ax +L$53: + cmp al,0 +L$54: + add byte ptr [bx+si],ch + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + adc byte ptr [bx+si],ch + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],dh + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + dec ax + add byte ptr -7cH[bx+si],bh + cld + test byte ptr 3000H[si],al + xor byte ptr -7cH[bx+si],bh + cld + test byte ptr 3800H[si],al + add ah,bh + xor al,80H + cld + add byte ptr [bx+si],al + add byte ptr 8[bp],bh + jle L$59 +L$55: + jle L$56 +L$56: + jle L$47 + nop + cld + nop + nop + sahf + add byte ptr -7eH[si],bh + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + sub byte ptr [bx+si],al + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + jo L$57 +L$57: + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + cmp byte ptr [si],al + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + jo L$58 +L$58: + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + sub byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp al,4 + jl L$64 + add byte ptr -7cH[bx+si],bh + test byte ptr 78H[si],al + dec ax + add byte ptr -7b7cH[si],al + DB 84H +L$59: + ;;;;js 4d8H + add byte ptr [bx+si],dl + cmp byte ptr 40H[bx+si],al + inc ax + cmp byte ptr [bx+si],dl + cmp byte ptr 40H[si],al + loopnz L$66 + inc ax + cmp ah,44H + jl L$60 + jl L$61 + jl L$62 + add al,dh + mov byte ptr -7d09H[bp+si],cl + add byte ptr 0c00H[bp+si],12H + DB 10H +L$60: + sbb byte ptr [bx+si],dh +L$61: + DB 10H, 90H +L$62: + ;;;;pusha + cmp al,0 + cmp byte ptr [si],al + cmp al,44H + jl L$63 +L$63: + add byte ptr [bx+si],bl + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + DB 1cH +L$64: + add byte ptr [bx+si],bh + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + sbb al,0 + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + jl L$65 +L$65: + js L$67 + inc sp +L$66: + inc sp + inc sp + add byte ptr [si],bh + inc sp + push sp + dec sp + inc sp + add byte ptr [bx+si],bl + and al,24H + push ds + add byte ptr ds:[0],bh + sbb al,22H + and bl,byte ptr [si] + add byte ptr ds:[0],bh + adc byte ptr [bx+si],al + adc byte ptr [bx+si],ah + inc ax + inc dx + cmp al,0 + add byte ptr [bx+si],al + add ah,bh + add byte ptr [bx+si],0 + add byte ptr [bx+si],al + cld + add al,4 + add byte ptr [bx+si],al + inc ax + inc sp + dec ax + push di + and word ptr 4[bx],ax + pop es + inc ax + inc sp + dec ax + push dx + dec dx + pop ds + DB 2 +L$67: + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl +L$68: + adc byte ptr [bx+si],al + add byte ptr [si],ah +L$69: + dec ax + nop + dec ax + and al,0 + add byte ptr [bx+si],al + dec ax + and al,12H + and al,48H + add byte ptr [bx+si],al + and cl,byte ptr -77deH[bx+si] + and cl,byte ptr -77deH[bx+si] + push bp + stosb + push bp + stosb + push bp + stosb + push bp + stosb + ;???? + ja L$68 + out dx,al + ;???? + ja L$69 + out dx,al + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + clc + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb al,bh + sbb al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[3636H],dh + div byte ptr ss:[3636H] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ;???? + add byte ptr ss:[bx+si],al + clc + sbb al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[0f636H],dh + push es + div byte ptr ds:[3636H] + add byte ptr ss:[bx+si],al + inc byte ptr ds:[36f6H] + test byte ptr ss:[0feH],0 + add byte ptr ds:[3636H],dh + inc byte ptr ss:[bx+si] + add byte ptr [bx+si],al + sbb byte ptr [bx+si],bl + clc + sbb al,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb bh,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb bh,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[3636H],dh + aaa + aaa + xor byte ptr [bx],bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bh + xor byte ptr [bx],dh + test word ptr ss:[bx+si],0ffH + add byte ptr [bx+si],al + add byte ptr [bx+si],al + inc word ptr [bx+si] + div word ptr ds:[3636H] + aaa + xor byte ptr [bx],dh + add byte ptr ss:[bx+si],al + inc word ptr [bx+si] + inc word ptr [bx+si] + add byte ptr [bx+si],al + test word ptr ss:[bx+si],36f7H + sbb byte ptr ss:[bx+si],bl + inc word ptr [bx+si] + inc word ptr [bx+si] + add byte ptr [bx+si],al + inc word ptr ss:[bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + inc word ptr [bx+si] + call dword ptr [bx+si] + sbb byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push word ptr ds:[3636H] + aas + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bh + push word ptr ss:[3636H] + sbb byte ptr [bx+si],bl + call dword ptr [bx+si] + call dword ptr [bx+si] + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + clc + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bl + DB 18H +L$70: + sbb byte ptr [bx+si],bl + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + inc word ptr [bx+si] + add byte ptr [bx+si],al + add bh,bh + ;???? + ;???? + push ax + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + ;???? + inc word ptr [bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr -6cH[bp+si],ah + mov byte ptr 62H[si],dl + add al,dh + mov al,dh + mov byte ptr -7f10H[bx+si],cl + add al,bh + mov byte ptr -7f80H[bx+si],al + add byte ptr [bx+si],0 + cld + dec ax + dec ax + dec ax + dec ax + dec ax + add ah,bh + test byte ptr 20H[bx+si],al + inc ax + test ah,bh + add byte ptr [si],bh + inc ax + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + js L$71 + inc ax + add byte ptr ds:[848H],dh + or byte ptr [bx+si],cl + or byte ptr [bx+si],al + cmp byte ptr [bx+si],dl + cmp byte ptr 44H[si],al + cmp byte ptr [bx+si],dl + cmp byte ptr -7cH[bx+si],bh + test ah,bh + test byte ptr 78H[si],al + js L$70 + test byte ptr 4848H[si],al + int 3 + add byte ptr 4[bx+si],bh + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + ;;;;insb + xchg ax,dx + xchg ax,dx + ;;;;insb + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,byte ptr 5aH[si] + and bl,byte ptr [si] + sbb byte ptr [bx+si],ah + inc ax + js L$73 + and byte ptr [bx+si],bl +L$71: + add byte ptr -7cH[bx+si],bh + test byte ptr -7b7cH[si],al + test byte ptr [bx+si],al + add ah,bh + add ah,bh + add ah,bh + add byte ptr [bx+si],al + and byte ptr [bx+si],ah + clc + and byte ptr [bx+si],ah + add al,bh + add byte ptr [bx+si],ah + adc byte ptr [bx+si],cl + adc byte ptr [bx+si],ah + add byte ptr [si],bh + or byte ptr [bx+si],dl + and byte ptr [bx+si],dl + or byte ptr [bx+si],al + jl L$72 +L$72: + or al,12H + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + nop + ;;;;pusha + add byte ptr [bx+si],dl + add byte ptr [si],bh +L$73: + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + xor cl,byte ptr [si] + xor cl,byte ptr [si] + add byte ptr [bx+si],bh + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + sbb byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr ds:[808H],cl + or byte ptr 28H[bx+si],cl + sbb byte ptr [bx+si],cl + cmp byte ptr [si],ah + and al,24H + and al,0 + add byte ptr [bx+si],al + cmp al,4 + cmp al,20H + cmp al,0 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,3cH + cmp al,3cH + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al +L$74: + DW offset L$1 +L$75: + DB 8 +L$76: + add byte ptr [bx+si],cl + DB 0 +L$77: + DW offset L$1 +L$78: + DW seg L$1 +L$79: + or byte ptr [bx+si],al +L$80: + or byte ptr [bx+si],al +L$81: + or byte ptr [bx+si],al +L$82: + inc word ptr [bx+si] +L$83: + add byte ptr [bx+si],al +L$84: + or byte ptr [bx+si],al +L$85: + add byte ptr [bx+si],al +MXSETFONT: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 0cH[bp] + test ax,ax + jne L$87 + mov ax,word ptr 0aH[bp] + cmp ax,1 + jb L$86 + xor ax,ax +L$86: + shl ax,1 + shl ax,1 + mov bx,ax + mov ax,word ptr L$74[bx] + mov word ptr L$77,ax + mov word ptr L$78,cs + mov al,byte ptr L$75[bx] + xor ah,ah + mov word ptr L$79,ax + mov word ptr L$84,ax + mov dl,byte ptr L$76[bx] + xor dh,dh + mov word ptr L$80,dx + mul dx + mov word ptr L$81,ax + mov word ptr L$84,ax + xor ax,ax + mov word ptr L$85,ax + jmp L$88 +L$87: + mov ax,0ffffH + mov bx,word ptr 8[bp] + cmp bx,10H + ja L$88 + mov dx,word ptr 6[bp] + cmp dx,20H + ja L$88 + mov word ptr L$79,bx + mov word ptr L$80,dx + mov ax,bx + add ax,7 + shr ax,1 + shr ax,1 + shr ax,1 + mul dx + mov word ptr L$81,ax + mov ax,word ptr 0aH[bp] + mov word ptr L$77,ax + mov ax,word ptr 0cH[bp] + mov word ptr L$78,ax + xor ax,ax +L$88: + pop ds + mov sp,bp + pop bp + retf 8 +MXSETTEXTCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 8[bp] + mov word ptr L$82,ax + mov ax,word ptr 6[bp] + mov word ptr L$83,ax + xor ax,ax + pop ds + mov sp,bp + pop bp + retf 4 +MXOUTCHAR: + push bp + mov bp,sp + sub sp,202H + push ds + push si + push es + push di + lds si,dword ptr cs:L$77 + mov al,byte ptr 6[bp] + xor ah,ah + mul word ptr cs:L$81 + add si,ax + mov ax,ss + mov es,ax + lea di,-200H[bp] + mov dx,word ptr cs:L$82 + mov ax,word ptr cs:L$80 + mov word ptr -202H[bp],ax +L$89: + mov cx,word ptr cs:L$79 + mov bh,byte ptr [si] + inc si + cmp cx,8 + jbe L$90 + mov bl,byte ptr [si] + inc si +L$90: + mov al,dl + shl bx,1 + jb L$91 + mov al,dh +L$91: + mov byte ptr es:[di],al + inc di + dec cx + jne L$90 + dec word ptr -202H[bp] + jne L$89 + lea ax,-200H[bp] + push es + push ax + push word ptr 0aH[bp] + push word ptr 8[bp] + push word ptr cs:L$79 + push word ptr cs:L$80 + push word ptr cs:L$83 + push cs + call near ptr MX_TEXT:MXPUTIMAGE + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 6 +MXOUTTEXT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 6[bp] +L$92: + mov al,byte ptr [si] + test al,al + je L$93 + inc si + push word ptr 0cH[bp] + push word ptr 0aH[bp] + push ax + push cs + call near ptr MXOUTCHAR + mov ax,word ptr cs:L$84 + add word ptr 0cH[bp],ax + mov ax,word ptr cs:L$85 + add word ptr 0aH[bp],ax + dec word ptr -202H[bp] + jne L$92 +L$93: + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 + retf +MXSETTEXTSTEP: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 8[bp] + mov word ptr L$84,ax + mov ax,word ptr 6[bp] + mov word ptr L$85,ax + pop ds + mov sp,bp + pop bp + retf 4 +MXGETTEXTSTEP: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr cs:L$84 + lds si,dword ptr 0aH[bp] + mov word ptr [si],ax + mov ax,word ptr cs:L$85 + lds si,dword ptr 6[bp] + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxot_.asm b/16/xw_/mxot_.asm new file mode 100755 index 00000000..e431b138 --- /dev/null +++ b/16/xw_/mxot_.asm @@ -0,0 +1,333 @@ +;----------------------------------------------------------- +; +; MXOT.ASM - Text functions +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +;WARN PRO +;NOWARN RES ; We use the reserved name 'WIDTH' +INCLUDE MODEX.DEF + +PUBLIC mxOutChar +PUBLIC mxOutText +PUBLIC mxSetFont +PUBLIC mxSetTextColor +PUBLIC mxGetTextStep +PUBLIC mxSetTextStep + +MAX_WIDTH EQU 16 ; Must be <= 16 +MAX_HEIGHT EQU 32 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD +EXTRN mxPutImage : FAR + +; Default 8x8 font +fnt_Default LABEL BYTE + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW OP_MOVE ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +;----------------------------------------------------------- +; +; Sets the current font. +; +; Input: +; Font = pointer to font data +; Width = width of font character in pixels +; Height = height of font character in pixels +; Output: +; AX = 0 on success, else invalid parameters +; +; Note: when the high word of Font (i.e. the segment) is zero, the low +; word is used to select one of the system fonts. +; +mxSetFont PROC FAR + push bp + mov bp,sp + sub sp,0 + push ds + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, WORD PTR Font[2] ; Get font segment + test ax, ax ; Null segment? + jnz @@UserFont ; No, install user font + +; Install system font + mov ax, WORD PTR Font[0] ; Get font number + cmp ax, MX_MAXSYSFONT ; Check range + jb @@SystemFont + xor ax, ax ; Out of range, use default font +@@SystemFont: + shl ax, 1 + shl ax, 1 + mov bx, ax + mov ax, tbl_SystemFont[bx] ; Get font offset + mov WORD PTR mx_FontPtr[0], ax + mov WORD PTR mx_FontPtr[2], cs + mov al, BYTE PTR tbl_SystemFont[bx+2] + xor ah, ah + mov [mx_FontWidth], ax + mov [mx_DeltaX], ax + mov dl, BYTE PTR tbl_SystemFont[bx+3] + xor dh, dh + mov [mx_FontHeight], dx + mul dx + mov [mx_FontCharSize], ax + mov [mx_DeltaX], ax + xor ax, ax + mov [mx_DeltaY], ax + jmp @@Exit + +; Install user font +@@UserFont: + mov ax, -1 ; Assume an error + mov bx, [bp+8] + cmp bx, MAX_WIDTH + ja @@Exit ; Invalid character width + mov dx, [bp+4] + cmp dx, MAX_HEIGHT + ja @@Exit ; Invalid character height + mov [mx_FontWidth], bx + mov [mx_FontHeight], dx + mov ax, bx + add ax, 7 + shr ax, 1 + shr ax, 1 + shr ax, 1 + mul dx + mov [mx_FontCharSize], ax + mov ax, WORD PTR Font[0] + mov WORD PTR mx_FontPtr[0], ax + mov ax, WORD PTR Font[2] + mov WORD PTR mx_FontPtr[2], ax + xor ax, ax + +@@Exit: + .pop ds + ASSUME ds:NOTHING + ;.leave ARG_SIZE +mxSetFont ENDP + +;----------------------------------------------------------- +; +; Sets the text color and raster op. +; +; Input: +; Color = text color (foreground + background*256) +; Op = raster op +; Output: +; none +; +mxSetTextColor PROC FAR + ARG Op:WORD, \ + Color:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [Color] + mov [mx_FontColor], ax + mov ax, [Op] + mov [mx_FontOp], ax + + xor ax, ax + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetTextColor ENDP + +;----------------------------------------------------------- +; +; Writes a character using the current font and attributes. +; +; Input: +; X, Y = video coordinates +; C = character to print +; Output: +; none +; +mxOutChar PROC FAR + ARG C:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \ + Count:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Gets the pointer to font data for the selected character + lds si, DWORD PTR [mx_FontPtr] + mov al, [C] + xor ah, ah + mul [mx_FontCharSize] ; Offset into font + add si, ax ; DS:SI -> font data for character + +; Converts font data into a 256-color linear image + mov ax, ss + mov es, ax + lea di, [Image] + mov dx, [mx_FontColor] + mov ax, [mx_FontHeight] + mov [Count], ax +@@HeightLoop: + mov cx, [mx_FontWidth] + mov bh, ds:[si] + inc si ; Get a byte from font data + cmp cx, 8 + jbe @@WidthLoop ; Ok for width <= 8 + mov bl, ds:[si] ; Get another byte + inc si +@@WidthLoop: + mov al, dl ; Assume foreground color + shl bx, 1 ; Is font bit set? + jc @@1 ; Yes, foreground is just great + mov al, dh ; Get background color +@@1: + mov es:[di], al ; Put pixel into image + inc di + dec cx + jnz @@WidthLoop + dec [Count] + jnz @@HeightLoop + +; Now pass image to mx_PutImage + lea ax, [Image] + push es + push ax ; Pointer to image + push [X] + push [Y] ; Image coordinates + push [mx_FontWidth] + push [mx_FontHeight] ; Image size + push [mx_FontOp] ; Raster op + call mxPutImage ; Write character + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxOutChar ENDP + +;----------------------------------------------------------- +; +; Writes a string at the coordinates specified. +; +; Input: +; X, Y = text coordinates +; S = pointer to ASCIIZ string +; Output: +; none +; +mxOutText PROC FAR + ARG S:DWORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [S] +@@Loop: + mov al, ds:[si] + test al, al ; End of string? + jz @@Exit ; Yes, exit + inc si + push [X] ; Display character + push [Y] + push ax + call mxOutChar + mov ax, [mx_DeltaX] + add [X], ax ; Bump X coordinate + mov ax, [mx_DeltaY] + add [Y], ax ; Bump Y coordinate + dec [Count] + jnz @@Loop + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE + ret +mxOutText ENDP + +;----------------------------------------------------------- +; +; Sets the distance between characters. +; +; Input: +; DeltaX = horizontal distance in pixels +; DeltaY = vertical distance in pixels +; Output: +; none +; +; Note: this function may be used to set the text direction. +; +mxSetTextStep PROC FAR + ARG DeltaY:WORD, \ + DeltaX:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [DeltaX] + mov [mx_DeltaX], ax + mov ax, [DeltaY] + mov [mx_DeltaY], ax + + .pop ds + .leave ARG_SIZE +mxSetTextStep ENDP + +;----------------------------------------------------------- +; +; Gets the current distance between characters. +; +; Input: +; DeltaX = pointer to horizontal distance in pixels (integer) +; DeltaY = pointer to vertical distance in pixels (integer) +; Output: +; none +; +mxGetTextStep PROC FAR + ARG DeltaY:DWORD, \ + DeltaX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + mov ax, [mx_DeltaX] + lds si, [DeltaX] + mov ds:[si], ax + mov ax, [mx_DeltaY] + lds si, [DeltaY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetTextStep ENDP + +MX_TEXT ENDS +END diff --git a/16/xw_/mxpb.asm b/16/xw_/mxpb.asm new file mode 100755 index 00000000..b8536fd6 --- /dev/null +++ b/16/xw_/mxpb.asm @@ -0,0 +1,4102 @@ + PUBLIC MX_SCANBUFFER +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_SCANBUFFER: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al +MX_TEXT ENDS + END diff --git a/16/xw_/mxpf.asm b/16/xw_/mxpf.asm new file mode 100755 index 00000000..f33158b8 --- /dev/null +++ b/16/xw_/mxpf.asm @@ -0,0 +1,327 @@ + PUBLIC MXFILLPOLY + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_SCANBUFFER:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov cx,word ptr [si] + sub cx,word ptr [bx] + jg L$2 + ret +L$2: + push bp + mov ax,word ptr 2[si] + mov bx,word ptr 2[bx] + sub ax,bx + jg L$4 + jl L$6 + mov ax,bx +L$3: + mov word ptr es:[di],ax + add di,4 + dec cx + jne L$3 + jmp L$8 +L$4: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$5: + mov word ptr es:[di],ax + add di,4 + add dx,bx + adc ax,bp + dec cx + jne L$5 + jmp L$8 +L$6: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$7: + mov word ptr es:[di],ax + add di,4 + sub dx,bx + sbb ax,bp + dec cx + jne L$7 +L$8: + pop bp + ret +MXFILLPOLY: + push bp + mov bp,sp + sub sp,1eH + push ds + push si + push es + push di + mov cx,word ptr 10H[bp] + cmp cx,3 + jae L$9 + jmp near ptr L$36 +L$9: + les di,dword ptr 0cH[bp] + lds si,dword ptr 8[bp] + mov word ptr -16H[bp],7fffH + mov word ptr -1aH[bp],8000H + mov word ptr -18H[bp],7fffH + mov word ptr -1eH[bp],8000H + xor dx,dx +L$10: + mov bx,word ptr es:[di] + shl bx,1 + shl bx,1 + add bx,si + mov ax,word ptr [bx] + cmp ax,word ptr -16H[bp] + jge L$11 + mov word ptr -16H[bp],ax + mov word ptr -0eH[bp],dx + mov word ptr -10H[bp],dx +L$11: + cmp ax,word ptr -1aH[bp] + jle L$12 + mov word ptr -1aH[bp],ax + mov word ptr -12H[bp],dx +L$12: + mov ax,word ptr 2[bx] + cmp ax,word ptr -18H[bp] + jge L$13 + mov word ptr -18H[bp],ax +L$13: + cmp ax,word ptr -1eH[bp] + jle L$14 + mov word ptr -1eH[bp],ax +L$14: + inc di + inc dx + inc di + inc dx + dec cx + jne L$10 + mov ax,word ptr -1aH[bp] + cmp ax,word ptr cs:MX_CLIPX1 + jge L$15 + jmp near ptr L$36 +L$15: + mov bx,word ptr -16H[bp] + cmp bx,word ptr cs:MX_CLIPX2 + jle L$16 + jmp near ptr L$36 +L$16: + sub ax,bx + jg L$17 + jmp near ptr L$36 +L$17: + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jge L$18 + jmp near ptr L$36 +L$18: + mov bx,word ptr -18H[bp] + cmp bx,word ptr cs:MX_CLIPY2 + jle L$19 + jmp near ptr L$36 +L$19: + sub ax,bx + jg L$20 + jmp near ptr L$36 +L$20: + dec word ptr 10H[bp] + shl word ptr 10H[bp],1 + mov es,word ptr cs:MX_CODESEGMENT + mov ax,offset MX_TEXT:MX_SCANBUFFER + mov word ptr -4[bp],ax + mov si,word ptr -0eH[bp] +L$21: + lds bx,dword ptr 0cH[bp] + mov di,word ptr [bx+si] + dec si + dec si + test si,si + jge L$22 + mov si,word ptr 10H[bp] +L$22: + mov word ptr -0eH[bp],si + mov si,word ptr [bx+si] + shl di,1 + shl di,1 + shl si,1 + shl si,1 + lds bx,dword ptr 8[bp] + add si,bx + add bx,di + mov di,word ptr -4[bp] + call near ptr L$1 + mov word ptr -4[bp],di + mov si,word ptr -0eH[bp] + cmp si,word ptr -12H[bp] + jne L$21 + mov ax,offset MX_TEXT:MX_SCANBUFFER+2 + mov word ptr -6[bp],ax + mov si,word ptr -10H[bp] +L$23: + lds bx,dword ptr 0cH[bp] + mov di,word ptr [bx+si] + inc si + inc si + cmp si,word ptr 10H[bp] + jbe L$24 + xor si,si +L$24: + mov word ptr -10H[bp],si + mov si,word ptr [bx+si] + shl di,1 + shl di,1 + shl si,1 + shl si,1 + lds bx,dword ptr 8[bp] + add si,bx + add bx,di + mov di,word ptr -6[bp] + call near ptr L$1 + mov word ptr -6[bp],di + mov si,word ptr -10H[bp] + cmp si,word ptr -12H[bp] + jne L$23 + mov si,offset MX_TEXT:MX_SCANBUFFER + mov ax,word ptr -16H[bp] + mov cx,word ptr -1aH[bp] + sub cx,ax + mov bx,word ptr cs:MX_CLIPX1 + sub bx,ax + jle L$25 + sub cx,bx + add ax,bx + mov word ptr -16H[bp],ax + shl bx,1 + shl bx,1 + add si,bx +L$25: + mov bx,ax + add bx,cx + sub bx,word ptr cs:MX_CLIPX2 + jle L$26 + sub cx,bx +L$26: + test cx,cx + jg L$27 + jmp near ptr L$36 +L$27: + mov word ptr -8[bp],cx + mov word ptr -4[bp],si + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr -18H[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$28 + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY2 + jg L$28 + jmp L$32 +L$28: + mov di,cx + inc di + sub si,4 +L$29: + dec di + je L$32 + add si,4 + mov ax,word ptr [si] + mov cx,word ptr 2[si] + mov dx,word ptr cs:MX_CLIPY2 + cmp ax,dx + jg L$31 + cmp cx,dx + jle L$30 + mov word ptr 2[si],dx + mov bx,cx + sub bx,dx + sub cx,ax + jle L$31 + mov cx,word ptr 2[si] +L$30: + mov dx,word ptr cs:MX_CLIPY1 + cmp cx,dx + jl L$31 + sub cx,ax + jle L$31 + cmp ax,dx + jge L$29 + mov word ptr [si],dx + sub dx,ax + cmp cx,dx + ja L$29 +L$31: + mov word ptr [si],0ffffH + jmp L$29 +L$32: + mov es,word ptr cs:MX_VIDEOSEGMENT + mov si,word ptr -4[bp] + mov cl,byte ptr -16H[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -2[bp],al + shr word ptr -16H[bp],1 + shr word ptr -16H[bp],1 +L$33: + mov ax,word ptr [si] + test ax,ax + js L$35 + mov cx,word ptr 2[si] + sub cx,ax + jle L$35 + mul word ptr cs:MX_BYTESPERLINE + add ax,word ptr -16H[bp] + mov di,ax + mov ah,byte ptr -2[bp] + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr 6[bp] + mov dx,word ptr cs:MX_BYTESPERLINE + shr cx,1 + jae L$34 + mov byte ptr es:[di],al + add di,dx + jcxz L$35 +L$34: + mov byte ptr es:[di],al + add di,dx + mov byte ptr es:[di],al + add di,dx + dec cx + jne L$34 +L$35: + rol byte ptr -2[bp],1 + adc word ptr -16H[bp],0 + add si,4 + dec word ptr -8[bp] + jne L$33 +L$36: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw_/mxpg.asm b/16/xw_/mxpg.asm new file mode 100755 index 00000000..d252576f --- /dev/null +++ b/16/xw_/mxpg.asm @@ -0,0 +1,457 @@ + PUBLIC MXGOURAUDPOLY + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_SCANBUFFER:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov cx,word ptr [si] + sub cx,word ptr [bx] + jg L$2 + ret +L$2: + push bp + push di + push cx + push ax + push dx + mov ax,word ptr 2[si] + mov bx,word ptr 2[bx] + sub ax,bx + jg L$4 + jl L$6 + mov ax,bx +L$3: + mov word ptr es:[di],ax + add di,8 + dec cx + jne L$3 + jmp L$8 +L$4: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$5: + mov word ptr es:[di],ax + add di,8 + add dx,bx + adc ax,bp + dec cx + jne L$5 + jmp L$8 +L$6: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$7: + mov word ptr es:[di],ax + add di,8 + sub dx,bx + sbb ax,bp + dec cx + jne L$7 +L$8: + pop bx + pop ax + pop cx + pop di + sub ax,bx + jg L$10 + jl L$12 + mov ah,bl + mov al,80H +L$9: + mov word ptr es:2[di],ax + add di,8 + dec cx + jne L$9 + jmp L$14 +L$10: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$11: + mov byte ptr es:3[di],al + mov byte ptr es:2[di],dh + add di,8 + add dx,bx + adc ax,bp + dec cx + jne L$11 + jmp L$14 +L$12: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$13: + mov byte ptr es:3[di],al + mov byte ptr es:2[di],dh + add di,8 + sub dx,bx + sbb ax,bp + dec cx + jne L$13 +L$14: + pop bp + ret +L$15: + mov ax,word ptr 6[si] + mov bx,word ptr 2[si] + cmp ah,bh + jg L$17 + jl L$19 + add ax,dx + mov dx,word ptr cs:MX_BYTESPERLINE +L$16: + mov byte ptr es:[di],ah + add di,dx + dec cx + jne L$16 + ret +L$17: + push bp + push si + mov si,bx + add si,dx + sub ax,bx + xor dx,dx + div cx + mov bp,ax + xor ax,ax + div cx + mov bx,ax + mov dx,8000H + mov ax,word ptr cs:MX_BYTESPERLINE + xchg ax,si +L$18: + mov byte ptr es:[di],ah + add dx,bx + adc ax,bp + add di,si + dec cx + jne L$18 + pop si + pop bp + ret +L$19: + push bp + push si + mov si,bx + add si,dx + sub ax,bx + neg ax + xor dx,dx + div cx + mov bp,ax + xor ax,ax + div cx + mov bx,ax + mov dx,8000H + mov ax,word ptr cs:MX_BYTESPERLINE + xchg ax,si +L$20: + mov byte ptr es:[di],ah + sub dx,bx + sbb ax,bp + add di,si + dec cx + jne L$20 + pop si + pop bp + ret +MXGOURAUDPOLY: + push bp + mov bp,sp + sub sp,1eH + push ds + push si + push es + push di + mov cx,word ptr 14H[bp] + cmp cx,3 + jae L$21 + jmp near ptr L$47 +L$21: + les di,dword ptr 10H[bp] + lds si,dword ptr 0cH[bp] + mov word ptr -16H[bp],7fffH + mov word ptr -1aH[bp],8000H + mov word ptr -18H[bp],7fffH + mov word ptr -1eH[bp],8000H + xor dx,dx +L$22: + mov bx,word ptr es:[di] + shl bx,1 + shl bx,1 + add bx,si + mov ax,word ptr [bx] + cmp ax,word ptr -16H[bp] + jge L$23 + mov word ptr -16H[bp],ax + mov word ptr -0eH[bp],dx + mov word ptr -10H[bp],dx +L$23: + cmp ax,word ptr -1aH[bp] + jle L$24 + mov word ptr -1aH[bp],ax + mov word ptr -12H[bp],dx +L$24: + mov ax,word ptr 2[bx] + cmp ax,word ptr -18H[bp] + jge L$25 + mov word ptr -18H[bp],ax +L$25: + cmp ax,word ptr -1eH[bp] + jle L$26 + mov word ptr -1eH[bp],ax +L$26: + inc di + inc di + inc dx + inc dx + dec cx + jne L$22 + mov ax,word ptr -1aH[bp] + cmp ax,word ptr cs:MX_CLIPX1 + jge L$27 + jmp near ptr L$47 +L$27: + mov bx,word ptr -16H[bp] + cmp bx,word ptr cs:MX_CLIPX2 + jle L$28 + jmp near ptr L$47 +L$28: + sub ax,bx + jg L$29 + jmp near ptr L$47 +L$29: + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jge L$30 + jmp near ptr L$47 +L$30: + mov bx,word ptr -18H[bp] + cmp bx,word ptr cs:MX_CLIPY2 + jle L$31 + jmp near ptr L$47 +L$31: + sub ax,bx + jg L$32 + jmp near ptr L$47 +L$32: + dec word ptr 14H[bp] + shl word ptr 14H[bp],1 + mov es,word ptr cs:MX_CODESEGMENT + mov ax,offset MX_TEXT:MX_SCANBUFFER + mov word ptr -4[bp],ax + mov si,word ptr -0eH[bp] +L$33: + lds bx,dword ptr 10H[bp] + mov di,word ptr [bx+si] + dec si + dec si + test si,si + jge L$34 + mov si,word ptr 14H[bp] +L$34: + mov word ptr -0eH[bp],si + mov si,word ptr [bx+si] + lds bx,dword ptr 8[bp] + shl di,1 + shl si,1 + mov ax,word ptr [bx+si] + mov dx,word ptr [bx+di] + lds bx,dword ptr 0cH[bp] + shl si,1 + shl di,1 + add si,bx + add bx,di + mov di,word ptr -4[bp] + call near ptr L$1 + mov word ptr -4[bp],di + mov si,word ptr -0eH[bp] + cmp si,word ptr -12H[bp] + jne L$33 + mov ax,offset MX_TEXT:MX_SCANBUFFER+4 + mov word ptr -6[bp],ax + mov si,word ptr -10H[bp] +L$35: + lds bx,dword ptr 10H[bp] + mov di,word ptr [bx+si] + inc si + inc si + cmp si,word ptr 14H[bp] + jbe L$36 + xor si,si +L$36: + mov word ptr -10H[bp],si + mov si,word ptr [bx+si] + lds bx,dword ptr 8[bp] + shl di,1 + shl si,1 + mov ax,word ptr [bx+si] + mov dx,word ptr [bx+di] + lds bx,dword ptr 0cH[bp] + shl si,1 + shl di,1 + add si,bx + add bx,di + mov di,word ptr -6[bp] + call near ptr L$1 + mov word ptr -6[bp],di + mov si,word ptr -10H[bp] + cmp si,word ptr -12H[bp] + jne L$35 + mov si,offset MX_TEXT:MX_SCANBUFFER + mov ax,word ptr -16H[bp] + mov cx,word ptr -1aH[bp] + sub cx,ax + mov bx,word ptr cs:MX_CLIPX1 + sub bx,ax + jle L$37 + sub cx,bx + add ax,bx + mov word ptr -16H[bp],ax + shl bx,1 + shl bx,1 + shl bx,1 + add si,bx +L$37: + mov bx,ax + add bx,cx + sub bx,word ptr cs:MX_CLIPX2 + jle L$38 + sub cx,bx +L$38: + test cx,cx + jg L$39 + jmp near ptr L$47 +L$39: + mov word ptr -8[bp],cx + mov word ptr -4[bp],si + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr -18H[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$40 + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY2 + jg L$40 + jmp L$44 +L$40: + mov di,cx + inc di + sub si,8 +L$41: + dec di + je L$44 + add si,8 + mov ax,word ptr [si] + mov cx,word ptr 4[si] + mov dx,word ptr cs:MX_CLIPY2 + cmp ax,dx + jg L$43 + cmp cx,dx + jle L$42 + mov word ptr 4[si],dx + mov bx,cx + sub bx,dx + sub cx,ax + jle L$43 + mov ax,word ptr 2[si] + sub ax,word ptr 6[si] + imul bx + idiv cx + add word ptr 6[si],ax + mov ax,word ptr [si] + mov cx,word ptr 4[si] +L$42: + mov dx,word ptr cs:MX_CLIPY1 + cmp cx,dx + jl L$43 + sub cx,ax + jle L$43 + cmp ax,dx + jge L$41 + mov word ptr [si],dx + sub dx,ax + cmp cx,dx + jbe L$43 + mov ax,word ptr 6[si] + sub ax,word ptr 2[si] + imul dx + idiv cx + add word ptr 2[si],ax + jmp L$41 +L$43: + mov word ptr [si],0ffffH + jmp L$41 +L$44: + mov es,word ptr cs:MX_VIDEOSEGMENT + mov si,word ptr -4[bp] + mov cl,byte ptr -16H[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -2[bp],al + shr word ptr -16H[bp],1 + shr word ptr -16H[bp],1 + mov ax,word ptr 6[bp] + mov ah,al + xor al,al + mov word ptr 6[bp],ax +L$45: + mov ax,word ptr [si] + test ax,ax + js L$46 + mov cx,word ptr 4[si] + sub cx,ax + jle L$46 + mul word ptr cs:MX_BYTESPERLINE + add ax,word ptr -16H[bp] + mov di,ax + mov ah,byte ptr -2[bp] + mov al,2 + mov dx,3c4H + out dx,ax + mov dx,word ptr 6[bp] + call near ptr L$15 +L$46: + rol byte ptr -2[bp],1 + adc word ptr -16H[bp],0 + add si,8 + dec word ptr -8[bp] + jne L$45 +L$47: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 10H +MX_TEXT ENDS + END diff --git a/16/xw_/mxpi.asm b/16/xw_/mxpi.asm new file mode 100755 index 00000000..2631d82f --- /dev/null +++ b/16/xw_/mxpi.asm @@ -0,0 +1,218 @@ + PUBLIC MXPUTIMAGE + EXTRN SUBCLIPIMAGE:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$2 + DW offset L$6 + DW offset L$10 + DW offset L$14 + DW offset L$18 + DW offset L$20 +L$2: + shr cx,1 + jb L$5 +L$3: + movsb + add si,3 + movsb + add si,3 + dec cx + jne L$3 +L$4: + ret +L$5: + movsb + add si,3 + jcxz L$4 + jmp L$3 +L$6: + shr cx,1 + jb L$9 +L$7: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + and word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$7 +L$8: + ret +L$9: + lodsb + and byte ptr es:[di],al + inc di + add si,3 + jcxz L$8 + jmp L$7 +L$10: + shr cx,1 + jb L$13 +L$11: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + or word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$11 +L$12: + ret +L$13: + lodsb + or byte ptr es:[di],al + inc di + add si,3 + jcxz L$12 + jmp L$11 +L$14: + shr cx,1 + jb L$17 +L$15: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + xor word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$15 +L$16: + ret +L$17: + lodsb + xor byte ptr es:[di],al + inc di + add si,3 + jcxz L$16 + jmp L$15 +L$18: + mov al,byte ptr [si] + cmp al,ah + je L$19 + mov byte ptr es:[di],al +L$19: + inc di + add si,4 + dec cx + jne L$18 + ret +L$20: + mov al,byte ptr [si] + add byte ptr es:[di],al + inc di + add si,4 + dec cx + jne L$20 + ret +MXPUTIMAGE: + push bp + mov bp,sp + sub sp,14H + push ds + push si + push es + push di + mov bx,word ptr 0eH[bp] + mov ax,word ptr 0cH[bp] + mov cx,word ptr 0aH[bp] + mov dx,word ptr 8[bp] + call near ptr MX_TEXT:SUBCLIPIMAGE + jae L$21 + jmp near ptr L$26 +L$21: + mov word ptr 8[bp],dx + add word ptr 10H[bp],si + mul word ptr cs:MX_BYTESPERLINE + mov di,bx + shr di,1 + shr di,1 + add di,ax + mov word ptr -0aH[bp],di + mov es,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -10H[bp],bl + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov si,6 +L$22: + mov word ptr -8[bp+si],bx + shr al,1 + adc bx,0 + dec si + dec si + jge L$22 + mov cl,byte ptr -10H[bp] + mov al,11H + shl al,cl + mov byte ptr -14H[bp],al + mov bx,word ptr 6[bp] + mov byte ptr -12H[bp],bh + xor bh,bh + cmp bl,5 + jbe L$23 + xor bl,bl +L$23: + shl bx,1 + mov ax,word ptr cs:L$1[bx] + mov word ptr -0cH[bp],ax + cld + mov byte ptr -0eH[bp],4 + lea bx,-8[bp] + mov ds,word ptr 12H[bp] +L$24: + cmp word ptr ss:[bx],0 + je L$26 + mov si,word ptr 10H[bp] + mov ah,byte ptr -14H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -10H[bp] + and ah,3 + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 8[bp] + mov di,word ptr -0aH[bp] +L$25: + push si + push di + mov cx,word ptr ss:[bx] + mov ah,byte ptr -12H[bp] + call word ptr -0cH[bp] + pop di + pop si + add si,word ptr 0aH[bp] + add di,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$25 + inc bx + inc bx + inc byte ptr -10H[bp] + rol byte ptr -14H[bp],1 + adc word ptr -0aH[bp],0 + inc word ptr 10H[bp] + dec byte ptr -0eH[bp] + jne L$24 +L$26: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0eH +MX_TEXT ENDS + END diff --git a/16/xw_/mxpn.asm b/16/xw_/mxpn.asm new file mode 100755 index 00000000..e4f20b10 --- /dev/null +++ b/16/xw_/mxpn.asm @@ -0,0 +1,34 @@ + PUBLIC MXPAN + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MXWAITDISPLAY:BYTE + EXTRN MXSTARTADDRESS:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXPAN: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + mov dx,word ptr 8[bp] + shr dx,1 + shr dx,1 + add ax,dx + push ax + call far ptr MXWAITDISPLAY + call far ptr MXSTARTADDRESS + mov dx,3daH + in al,dx + mov dx,3c0H + mov al,33H + out dx,al + mov al,byte ptr 8[bp] + and al,3 + shl al,1 + out dx,al + xor ax,ax + mov sp,bp + pop bp + retf 4 +MX_TEXT ENDS + END diff --git a/16/xw_/mxpp.asm b/16/xw_/mxpp.asm new file mode 100755 index 00000000..42f7a6f0 --- /dev/null +++ b/16/xw_/mxpp.asm @@ -0,0 +1,84 @@ + PUBLIC MXGETPIXEL + PUBLIC MXPUTPIXEL + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETPIXEL: + push bp + mov bp,sp + sub sp,0 + push ds + push si + xor ax,ax + mov si,word ptr 8[bp] + cmp si,word ptr cs:MX_CLIPX1 + jl L$1 + cmp si,word ptr cs:MX_CLIPX2 + jg L$1 + mov bx,word ptr 6[bp] + cmp bx,word ptr cs:MX_CLIPY1 + jl L$1 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$1 + mov al,4 + mov ah,byte ptr 8[bp] + and ah,3 + mov dx,3ceH + out dx,ax + mov ds,word ptr cs:MX_VIDEOSEGMENT + mov ax,bx + mul word ptr cs:MX_BYTESPERLINE + shr si,1 + shr si,1 + add si,ax + mov al,byte ptr [si] + xor ah,ah +L$1: + pop si + pop ds + mov sp,bp + pop bp + retf 4 +MXPUTPIXEL: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov si,word ptr 0aH[bp] + cmp si,word ptr cs:MX_CLIPX1 + jl L$2 + cmp si,word ptr cs:MX_CLIPX2 + jg L$2 + mov ax,word ptr 8[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$2 + cmp ax,word ptr cs:MX_CLIPY2 + jg L$2 + mov ds,word ptr cs:MX_VIDEOSEGMENT + mul word ptr cs:MX_BYTESPERLINE + shr si,1 + shr si,1 + add si,ax + mov cl,byte ptr 0aH[bp] + and cl,3 + mov ax,102H + shl ah,cl + mov dx,3c4H + out dx,ax + mov al,byte ptr 6[bp] + mov byte ptr [si],al +L$2: + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 6 +MX_TEXT ENDS + END diff --git a/16/xw_/mxra.asm b/16/xw_/mxra.asm new file mode 100755 index 00000000..a71b4a0e --- /dev/null +++ b/16/xw_/mxra.asm @@ -0,0 +1,17 @@ + PUBLIC MXROWADDRESS +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXROWADDRESS: + push bp + mov bp,sp + sub sp,0 + mov dx,3d4H + mov al,13H + mov ah,byte ptr 6[bp] + out dx,ax + xor ax,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxrp.asm b/16/xw_/mxrp.asm new file mode 100755 index 00000000..03239eff --- /dev/null +++ b/16/xw_/mxrp.asm @@ -0,0 +1,72 @@ + PUBLIC MXROTATEPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXROTATEPALETTE: + push bp + mov bp,sp + sub sp,300H + push ds + push si + push es + push di + mov bx,word ptr 8[bp] + add bx,bx + add bx,word ptr 8[bp] + lds si,dword ptr 0aH[bp] + push ss + pop es + lea di,-300H[bp] + cld + mov ax,word ptr 6[bp] + mov dx,ax + test ax,ax + je L$2 + jl L$1 + add ax,ax + add dx,ax + sub bx,dx + add si,bx + push si + mov cx,dx + rep movsb + mov es,word ptr 0cH[bp] + mov di,si + dec di + pop si + dec si + mov cx,bx + std + rep movsb + push ss + pop ds + lea si,-300H[bp] + les di,dword ptr 0aH[bp] + mov cx,dx + cld + rep movsb + jmp L$2 +L$1: + add ax,ax + add dx,ax + neg dx + sub bx,dx + mov cx,dx + rep movsb + les di,dword ptr 0aH[bp] + mov cx,bx + rep movsb + push ss + pop ds + lea si,-300H[bp] + mov cx,dx + rep movsb +L$2: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxsa.asm b/16/xw_/mxsa.asm new file mode 100755 index 00000000..642d2dd7 --- /dev/null +++ b/16/xw_/mxsa.asm @@ -0,0 +1,22 @@ + PUBLIC MXSTARTADDRESS +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSTARTADDRESS: + push bp + mov bp,sp + sub sp,0 + mov bx,word ptr 6[bp] + mov dx,3d4H + mov al,0cH + mov ah,bh + cli + out dx,ax + mov al,0dH + mov ah,bl + out dx,ax + sti + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxsc.asm b/16/xw_/mxsc.asm new file mode 100755 index 00000000..7d8bd47b --- /dev/null +++ b/16/xw_/mxsc.asm @@ -0,0 +1,26 @@ + PUBLIC MXSETCOLOR +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSETCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr 0cH[bp] + mov dx,3c8H + out dx,al + inc dx + mov al,byte ptr 0aH[bp] + out dx,al + mov al,byte ptr 8[bp] + out dx,al + mov al,byte ptr 6[bp] + out dx,al + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxsi.asm b/16/xw_/mxsi.asm new file mode 100755 index 00000000..c9223532 --- /dev/null +++ b/16/xw_/mxsi.asm @@ -0,0 +1,220 @@ + PUBLIC MXSTRETCHIMAGE + EXTRN SUBCLIPBOX:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$8 + DW offset L$10 + DW offset L$12 + DW offset L$14 + DW offset L$16 + DW offset L$19 +MXSTRETCHIMAGE: + push bp + mov bp,sp + sub sp,14H + push ds + push si + push es + push di + xor dx,dx + mov ax,word ptr 0eH[bp] + mov bx,word ptr 0aH[bp] + div bx + mov word ptr -0aH[bp],ax + xor ax,ax + div bx + mov word ptr -0cH[bp],ax + xor dx,dx + mov ax,word ptr 0cH[bp] + mov bx,word ptr 8[bp] + div bx + mov word ptr -0eH[bp],ax + xor ax,ax + div bx + mov word ptr -10H[bp],ax + mov bx,word ptr 12H[bp] + mov ax,word ptr 10H[bp] + mov cx,word ptr 0aH[bp] + mov dx,word ptr 8[bp] + call near ptr MX_TEXT:SUBCLIPBOX + jae L$2 + jmp near ptr L$7 +L$2: + mov word ptr 0aH[bp],cx + mov word ptr 8[bp],dx + sub word ptr 12H[bp],bx + sub word ptr 10H[bp],ax + mul word ptr cs:MX_BYTESPERLINE + mov di,bx + shr di,1 + shr di,1 + add di,ax + mov word ptr -2[bp],di + mov es,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -6[bp],bl + mov cl,bl + mov al,11H + shl al,cl + mov byte ptr -14H[bp],al + mov ax,word ptr 10H[bp] + test ax,ax + je L$3 + mov bx,ax + mul word ptr -10H[bp] + mov cx,dx + mov ax,bx + mul word ptr -0eH[bp] + add ax,cx + mul word ptr 0eH[bp] + add word ptr 14H[bp],ax +L$3: + mov ax,word ptr 12H[bp] + test ax,ax + je L$4 + mov bx,ax + mul word ptr -0cH[bp] + mov cx,dx + mov ax,bx + mul word ptr -0aH[bp] + add ax,cx + add word ptr 14H[bp],ax +L$4: + mov ax,word ptr -0eH[bp] + mul word ptr 0eH[bp] + mov word ptr -0eH[bp],ax + mov bx,word ptr 6[bp] + mov byte ptr -8[bp],bh + xor bh,bh + cmp bl,5 + jbe L$5 + xor bl,bl +L$5: + shl bx,1 + mov ax,word ptr cs:L$1[bx] + mov word ptr -4[bp],ax + mov ds,word ptr 16H[bp] + xor ax,ax + mov word ptr -12H[bp],ax +L$6: + mov si,word ptr 14H[bp] + mov ah,byte ptr -14H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -6[bp] + and ah,3 + mov al,4 + mov dx,3ceH + out dx,ax + mov cx,word ptr 8[bp] + mov di,word ptr -2[bp] + mov ah,byte ptr -8[bp] + xor bx,bx + mov dx,word ptr cs:MX_BYTESPERLINE + call word ptr -4[bp] + inc byte ptr -6[bp] + rol byte ptr -14H[bp],1 + adc word ptr -2[bp],0 + mov dx,word ptr -0cH[bp] + mov ax,word ptr -0aH[bp] + add word ptr -12H[bp],dx + adc word ptr 14H[bp],ax + dec word ptr 0aH[bp] + jne L$6 +L$7: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 12H +L$8: + mov al,byte ptr [si] + mov byte ptr es:[di],al + add di,dx + dec cx + je L$9 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$8 + add si,word ptr 0eH[bp] + jmp L$8 +L$9: + ret +L$10: + mov al,byte ptr [si] + and byte ptr es:[di],al + add di,dx + dec cx + je L$11 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$10 + add si,word ptr 0eH[bp] + jmp L$10 +L$11: + ret +L$12: + mov al,byte ptr [si] + or byte ptr es:[di],al + add di,dx + dec cx + je L$13 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$12 + add si,word ptr 0eH[bp] + jmp L$12 +L$13: + ret +L$14: + mov al,byte ptr [si] + xor byte ptr es:[di],al + add di,dx + dec cx + je L$15 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$14 + add si,word ptr 0eH[bp] + jmp L$14 +L$15: + ret +L$16: + mov al,byte ptr [si] + cmp al,ah + je L$17 + mov byte ptr es:[di],al +L$17: + add di,dx + dec cx + je L$18 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$16 + add si,word ptr 0eH[bp] + jmp L$16 +L$18: + ret +L$19: + mov al,byte ptr [si] + add byte ptr es:[di],al + add di,dx + dec cx + je L$20 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$19 + add si,word ptr 0eH[bp] + jmp L$19 +L$20: + ret +MX_TEXT ENDS + END diff --git a/16/xw_/mxsl.asm b/16/xw_/mxsl.asm new file mode 100755 index 00000000..109ce3ba --- /dev/null +++ b/16/xw_/mxsl.asm @@ -0,0 +1,36 @@ + PUBLIC MXSTARTLINE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSTARTLINE: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + xchg ax,bx + mov dx,3daH +L$1: + in al,dx + test al,8 + jne L$1 + mov dx,3d4H + mov al,0cH + mov ah,bh + cli + out dx,ax + mov al,0dH + mov ah,bl + out dx,ax + sti + mov dx,3daH +L$2: + in al,dx + test al,8 + je L$2 + xor ax,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxsm.asm b/16/xw_/mxsm.asm new file mode 100755 index 00000000..96e746d3 --- /dev/null +++ b/16/xw_/mxsm.asm @@ -0,0 +1,449 @@ + PUBLIC MX_SCREENWIDTH + PUBLIC MX_SCREENHEIGHT + PUBLIC MX_BYTESPERLINE + PUBLIC MXSETMODE + PUBLIC MXCHANGEMODE + PUBLIC MXGETASPECT + PUBLIC MXGETSCREENSIZE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MXSETSYSCLIPREGION:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_SCREENWIDTH: + add byte ptr [bx+si],al +MX_SCREENHEIGHT: + add byte ptr [bx+si],al +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +MX_BYTESPERLINE: + add byte ptr [bx+si],al +L$3: + or word ptr 14H[bx+si],ax + add byte ptr [bx],dl + jcxz L$4 +L$4: + DB 0 +L$5: + or word ptr 14H[bx+di],ax + add byte ptr [bx],dl + jcxz L$6 +L$6: + DB 0 +L$7: + add byte ptr 1[bx],bl + dec di + add dl,byte ptr 3[bx+si] + add byte ptr [si],54H + add ax,1380H + sub byte ptr [bx+si],al + DB 0 +L$8: + add byte ptr 1[bp+di],ch + pop cx + add bl,byte ptr 3[bp+si] + mov es,word ptr [si] + pop si + add ax,138aH + sub ax,0 + push es + mov di,1f07H + adc byte ptr -7aefH[bp+di],al + adc bl,byte ptr 15H[di] + arpl word ptr ds:[0baH],dx + DB 0 +L$9: + push es + DD ds:[7bfH] + pushf + adc word ptr -70eeH[bp],cx + adc ax,1696H + mov cx,0 +L$10: + push es + or ax,3e07H + adc dl,ch + adc word ptr -20eeH[si],cx + adc ax,16e7H + push es + add byte ptr [bx+si],al +L$11: + add byte ptr 1[si],dh + arpl word ptr [bp+si],ax + add dx,word ptr fs:6804H[bx] + add ax,695H + xchg byte ptr [bx],al + lock or word ptr 0fH[bx+si],sp + xor word ptr [bx+si],dx + pop bx + adc word ptr 5712H[di],cx + adc si,word ptr [bp+si] + adc al,0 + adc ax,1660H + adc byte ptr [bx],0e3H + add byte ptr [bx+si],al +L$12: + arpl word ptr ds:[500H],ax + add byte ptr 1[bx+si],al + enter 1a00H,0 + DW offset L$9 + DW offset L$5 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$13: + jcxz L$14 + DB 0 +L$14: + add word ptr [bx+si],ax + inc ax + add ax,si + add byte ptr [bp+si],bl + add byte ptr [bp+si],bl + DW offset L$5 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$15: + arpl word ptr ds:[0a00H],ax + add byte ptr 1[bx+si],al + nop + add word ptr [bp+si],bx + add byte ptr [bp+si],cl + DW offset L$3 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$16: + jcxz L$17 + DB 0 +L$17: + add al,byte ptr [bx+si] + inc ax + add ax,sp + DD L$18 +L$18: + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$19: + sbb ax,word ptr [eax] + adc al,0 + push 0c801H + add byte ptr [bp+si],ch + add byte ptr [bp+si],cl + DW offset L$5 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$20: + out 9,ax + add byte ptr [bx+si],cl + add byte ptr 1[bx+si],ch + lock add byte ptr [bp+si],ch + add byte ptr [bp+si],bl + DW offset L$5 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$21: + sbb ax,word ptr [eax] + sub byte ptr [bx+si],al + push 9001H + add word ptr [bp+si],bp + add byte ptr [bp+si],cl + DW offset L$3 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$22: + out 9,ax + add byte ptr [bx+si],dl + add byte ptr 1[bx+si],ch + loopnz L$23 + DW offset L$8 +L$23 equ $-1 + DW offset L$10 + DW offset L$3 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$24: + mov word ptr ds:[0],ax + add byte ptr [bx+si],al + inc ax + add word ptr 1a00H[bx],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],dl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$25: + mov word ptr 0,ax + add byte ptr [bx+si],al + inc ax + add word ptr 1a00H[bx],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$26: + cmpsw + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push 0e001H + add word ptr [bp+si],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],dl + add byte ptr [bx+si],al + add al,bl + DB 2 +L$27: + cmpsw + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push 0e001H + add word ptr [bp+si],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add al,bl + DB 2 +L$28: + out 1,ax + add byte ptr [bp+si],al + add byte ptr 5801H[bx+si],dl + add ch,byte ptr [bp+si] + add byte ptr [bx+si],al + pop word ptr [bp+si] +L$29: + DW offset L$24 + DW offset L$12 + DW offset L$13 + DW offset L$25 + DW offset L$15 + DW offset L$16 + DW offset L$26 + DW offset L$19 + DW offset L$20 + DW offset L$27 + DW offset L$21 + DW offset L$22 + DW offset L$28 +L$30: + mov ax,3 + int 10H + mov word ptr MX_SCREENHEIGHT,0 + mov word ptr MX_BYTESPERLINE,0 + ret +MXSETMODE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ds,word ptr cs:MX_CODESEGMENT + mov si,word ptr 6[bp] + cmp si,0dH + jbe L$31 + jmp near ptr L$36 +L$31: + test si,si + jne L$32 + call near ptr L$30 + jmp near ptr L$36 +L$32: + dec si + shl si,1 + mov si,word ptr L$29[si] + cld + push si + mov ax,13H + int 10H + pop si + mov dx,3c4H + mov ax,604H + out dx,ax + mov ax,100H + out dx,ax + mov dx,3c2H + lodsb + out dx,al + mov dx,3c4H + mov ax,300H + out dx,ax + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + and al,7fH + out dx,al + lodsw + mov word ptr L$1,ax + lodsw + mov word ptr L$2,ax + lodsw + mov word ptr MX_SCREENWIDTH,ax + shr ax,1 + shr ax,1 + mov word ptr MX_BYTESPERLINE,ax + lodsw + mov word ptr MX_SCREENHEIGHT,ax + mov bx,si + mov dx,3d4H +L$33: + mov si,word ptr [bx] + inc bx + inc bx + test si,si + je L$35 +L$34: + lodsw + test ax,ax + je L$33 + out dx,ax + jmp L$34 +L$35: + push word ptr MX_SCREENWIDTH + push word ptr [bx] + push cs + call near ptr MX_TEXT:MXSETSYSCLIPREGION + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov es,word ptr MX_TEXT:MX_VIDEOSEGMENT + xor di,di + mov cx,8000H + xor ax,ax + rep stosw + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + or al,80H + out dx,al +L$36: + xor ax,ax + mov ax,word ptr MX_SCREENWIDTH + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 2 +MXCHANGEMODE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ds,word ptr cs:MX_CODESEGMENT + mov si,word ptr 6[bp] + cmp si,0dH + ja L$40 + test si,si + je L$40 + dec si + shl si,1 + mov si,word ptr L$29[si] + cld + mov dx,3c4H + mov ax,604H + out dx,ax + mov ax,100H + out dx,ax + mov dx,3c2H + lodsb + out dx,al + mov dx,3c4H + mov ax,300H + out dx,ax + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + and al,7fH + out dx,al + lodsw + mov word ptr L$1,ax + lodsw + mov word ptr L$2,ax + lodsw + mov word ptr MX_SCREENWIDTH,ax + lodsw + mov word ptr MX_SCREENHEIGHT,ax + mov bx,si + mov dx,3d4H +L$37: + mov si,word ptr [bx] + inc bx + inc bx + test si,si + je L$39 +L$38: + lodsw + test ax,ax + je L$37 + cmp al,13H + je L$38 + out dx,ax + jmp L$38 +L$39: + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + or al,80H + out dx,al +L$40: + xor ax,ax + mov ax,word ptr MX_SCREENWIDTH + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 2 +MXGETASPECT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov ax,word ptr cs:L$1 + mov word ptr [si],ax + lds si,dword ptr 6[bp] + mov ax,word ptr cs:L$2 + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MXGETSCREENSIZE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov ax,word ptr cs:MX_SCREENWIDTH + mov word ptr [si],ax + lds si,dword ptr 6[bp] + mov ax,word ptr cs:MX_SCREENHEIGHT + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxsp.asm b/16/xw_/mxsp.asm new file mode 100755 index 00000000..3385a6cf --- /dev/null +++ b/16/xw_/mxsp.asm @@ -0,0 +1,33 @@ + PUBLIC MXSETPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSETPALETTE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov cx,word ptr 6[bp] + mov ax,word ptr 8[bp] + mov dx,3c8H + out dx,al + inc dx + cld + cli +L$1: + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + loop L$1 + sti + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxss.asm b/16/xw_/mxss.asm new file mode 100755 index 00000000..558584c3 --- /dev/null +++ b/16/xw_/mxss.asm @@ -0,0 +1,44 @@ + PUBLIC MXSPLITSCREEN +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSPLITSCREEN: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + shl ax,1 + mov bh,ah + mov bl,ah + and bx,201H + mov cl,4 + shl bx,cl + shl bh,1 + mov dx,3d4H + mov ah,al + mov al,18H + out dx,ax + mov al,7 + out dx,al + inc dx + in al,dx + dec dx + mov ah,al + and ah,0efH + or ah,bl + mov al,7 + out dx,ax + mov al,9 + out dx,al + inc dx + in al,dx + dec dx + mov ah,al + and ah,0bfH + or ah,bh + mov al,9 + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxtl.asm b/16/xw_/mxtl.asm new file mode 100755 index 00000000..3f791b41 --- /dev/null +++ b/16/xw_/mxtl.asm @@ -0,0 +1,122 @@ + PUBLIC MXPUTTILE + PUBLIC MXTRANSPUTTILE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXPUTTILE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ax,word ptr 0aH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 0cH[bp] + shr di,1 + shr di,1 + add di,ax + mov es,word ptr cs:MX_VIDEOSEGMENT + lds si,dword ptr 0eH[bp] + shr word ptr 8[bp],1 + shr word ptr 8[bp],1 + mov cl,byte ptr 0cH[bp] + and cl,3 + mov ah,11H + shl ah,cl + mov word ptr 0aH[bp],4 + mov bx,word ptr cs:MX_BYTESPERLINE + sub bx,word ptr 8[bp] +L$1: + mov al,2 + mov dx,3c4H + out dx,ax + mov word ptr 0cH[bp],di + mov dx,word ptr 6[bp] +L$2: + mov cx,word ptr 8[bp] + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + add di,bx + dec dx + jne L$2 + mov di,word ptr 0cH[bp] + rol ah,1 + adc di,0 + dec word ptr 0aH[bp] + jne L$1 + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MXTRANSPUTTILE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ax,word ptr 0aH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 0cH[bp] + shr di,1 + shr di,1 + add di,ax + mov es,word ptr cs:MX_VIDEOSEGMENT + lds si,dword ptr 0eH[bp] + shr word ptr 8[bp],1 + shr word ptr 8[bp],1 + mov cl,byte ptr 0cH[bp] + and cl,3 + mov ah,11H + shl ah,cl + mov word ptr 0aH[bp],4 + mov bx,word ptr cs:MX_BYTESPERLINE + sub bx,word ptr 8[bp] +L$3: + mov al,2 + mov dx,3c4H + out dx,ax + mov word ptr 0cH[bp],di + mov dx,word ptr 6[bp] +L$4: + mov cx,word ptr 8[bp] + jcxz L$7 +L$5: + mov al,byte ptr [si] + test al,al + je L$6 + mov byte ptr es:[di],al +L$6: + inc si + inc di + dec cx + jne L$5 +L$7: + add di,bx + dec dx + jne L$4 + mov di,word ptr 0cH[bp] + rol ah,1 + adc di,0 + dec word ptr 0aH[bp] + jne L$3 + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw_/mxvs.asm b/16/xw_/mxvs.asm new file mode 100755 index 00000000..c4728ff5 --- /dev/null +++ b/16/xw_/mxvs.asm @@ -0,0 +1,68 @@ + PUBLIC MXSETVIRTUALSCREEN + PUBLIC MXGETVIRTUALSCREEN + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MXROWADDRESS:BYTE + EXTRN MXSETSYSCLIPREGION:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +MXSETVIRTUALSCREEN: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,1 + cmp word ptr 8[bp],140H + jb L$3 + push ax + mov dx,4 + xor ax,ax + div word ptr 8[bp] + cmp word ptr 6[bp],ax + pop ax + ja L$3 + mov ax,word ptr 8[bp] + and ax,0fff8H + mov word ptr L$1,ax + shr ax,1 + shr ax,1 + mov word ptr MX_TEXT:MX_BYTESPERLINE,ax + shr ax,1 + push ax + call far ptr MXROWADDRESS + mov ax,word ptr 6[bp] + mov word ptr L$2,ax + push word ptr 8[bp] + push word ptr 6[bp] + call far ptr MXSETSYSCLIPREGION + xor ax,ax +L$3: + pop ds + mov sp,bp + pop bp + retf 4 +MXGETVIRTUALSCREEN: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr cs:L$1 + lds si,dword ptr 0aH[bp] + mov word ptr [si],ax + mov ax,word ptr cs:L$2 + lds si,dword ptr 6[bp] + mov word ptr [si],ax + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw_/mxwd.asm b/16/xw_/mxwd.asm new file mode 100755 index 00000000..c0d19aa2 --- /dev/null +++ b/16/xw_/mxwd.asm @@ -0,0 +1,12 @@ + PUBLIC MXWAITDISPLAY +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWAITDISPLAY: + mov dx,3daH +L$1: + in al,dx + test al,8 + jne L$1 + retf +MX_TEXT ENDS + END diff --git a/16/xw_/mxwm.asm b/16/xw_/mxwm.asm new file mode 100755 index 00000000..7dc66acc --- /dev/null +++ b/16/xw_/mxwm.asm @@ -0,0 +1,18 @@ + PUBLIC MXWRITEMODE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWRITEMODE: + push bp + mov bp,sp + sub sp,0 + mov dx,3ceH + mov ah,byte ptr 6[bp] + and ah,3 + or ah,40H + mov al,5 + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxwp.asm b/16/xw_/mxwp.asm new file mode 100755 index 00000000..e03c4040 --- /dev/null +++ b/16/xw_/mxwp.asm @@ -0,0 +1,30 @@ + PUBLIC MXWRITEPLANE + PUBLIC MXREADPLANE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWRITEPLANE: + push bp + mov bp,sp + sub sp,0 + mov ah,byte ptr 6[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov sp,bp + pop bp + retf 2 +MXREADPLANE: + push bp + mov bp,sp + sub sp,0 + mov al,4 + mov ah,byte ptr 6[bp] + and ah,3 + mov dx,3ceH + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw_/mxwr.asm b/16/xw_/mxwr.asm new file mode 100755 index 00000000..0d228d8b --- /dev/null +++ b/16/xw_/mxwr.asm @@ -0,0 +1,12 @@ + PUBLIC MXWAITRETRACE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWAITRETRACE: + mov dx,3daH +L$1: + in al,dx + test al,8 + je L$1 + retf +MX_TEXT ENDS + END diff --git a/16/xw_/readme.txt b/16/xw_/readme.txt new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw_/readme.txt @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw_/xw.bat b/16/xw_/xw.bat new file mode 100755 index 00000000..1fd24399 --- /dev/null +++ b/16/xw_/xw.bat @@ -0,0 +1,39 @@ +@echo off +wdis -a MXBB.OBJ > mxbb.asm +wdis -a MXCC.OBJ > mxcc.asm +wdis -a MXCG.OBJ > mxcg.asm +wdis -a MXCL.OBJ > mxcl.asm +wdis -a MXCR.OBJ > mxcl.asm +wdis -a MXFB.OBJ > mxfb.asm +wdis -a MXFP.OBJ > mxfp.asm +wdis -a MXGC.OBJ > mxgc.asm +wdis -a MXGI.OBJ > mxgi.asm +wdis -a MXGM.OBJ > mxgm.asm +wdis -a MXGP.OBJ > mxgp.asm +wdis -a MXGV.OBJ > mxgv.asm +wdis -a MXHL.OBJ > mxhl.asm +wdis -a MXIT.OBJ > mxit.asm +wdis -a MXLL.OBJ > mxll.asm +wdis -a MXLN.OBJ > mxln.asm +wdis -a MXOT.OBJ > mxot.asm +wdis -a MXPB.OBJ > mxpb.asm +wdis -a MXPF.OBJ > mxpf.asm +wdis -a MXPG.OBJ > mxpg.asm +wdis -a MXPI.OBJ > mxpi.asm +wdis -a MXPN.OBJ > mxpn.asm +wdis -a MXPP.OBJ > mxpp.asm +wdis -a MXRA.OBJ > mxra.asm +wdis -a MXRP.OBJ > mxrp.asm +wdis -a MXSA.OBJ > mxsa.asm +wdis -a MXSC.OBJ > mxsc.asm +wdis -a MXSI.OBJ > mxsi.asm +wdis -a MXSL.OBJ > mxsl.asm +wdis -a MXSM.OBJ > mxsm.asm +wdis -a MXSP.OBJ > mxsp.asm +wdis -a MXSS.OBJ > mxss.asm +wdis -a MXTL.OBJ > mxtl.asm +wdis -a MXVS.OBJ > mxvs.asm +wdis -a MXWD.OBJ > mxwd.asm +wdis -a MXWM.OBJ > mxwm.asm +wdis -a MXWP.OBJ > mxwp.asm +wdis -a MXWR.OBJ > mxwr.asm diff --git a/16/xw__/default.fnt b/16/xw__/default.fnt new file mode 100755 index 00000000..12eb22cb --- /dev/null +++ b/16/xw__/default.fnt @@ -0,0 +1,260 @@ +; +; MODEX library default font +; Copyright (c) 1993-1994 by Alessandro Scotti +; + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #0 + DB 07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh ; #1 + DB 07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh ; #2 + DB 06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h ; #3 + DB 010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h ; #4 + DB 010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh ; #5 + DB 010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh ; #6 + DB 000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h ; #7 + DB 0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh ; #8 + DB 000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h ; #9 + DB 0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh ; #10 + DB 007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h ; #11 + DB 07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h ; #12 + DB 01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h ; #13 + DB 03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h ; #14 + DB 099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h ; #15 + DB 000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h ; #16 + DB 000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h ; #17 + DB 010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h ; #18 + DB 048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h ; #19 + DB 07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h ; #20 + DB 03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch ; #21 + DB 000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h ; #22 + DB 038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh ; #23 + DB 000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h ; #24 + DB 000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h ; #25 + DB 000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h ; #26 + DB 000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h ; #27 + DB 000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h ; #28 + DB 000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h ; #29 + DB 000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h ; #30 + DB 000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h ; #31 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; + DB 010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h ; ! + DB 000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h ; " + DB 024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h ; # + DB 038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h ; $ + DB 000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h ; % + DB 038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h ; & + DB 020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h ; ' + DB 010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h ; ( + DB 040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h ; ) + DB 000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h ; * + DB 000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h ; + + DB 000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h ; , + DB 000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h ; - + DB 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h ; . + DB 000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h ; / + DB 07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h ; 0 + DB 010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h ; 1 + DB 078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h ; 2 + DB 078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h ; 3 + DB 01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h ; 4 + DB 0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h ; 5 + DB 078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h ; 6 + DB 0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h ; 7 + DB 078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h ; 8 + DB 078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h ; 9 + DB 000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h ; : + DB 000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h ; ; + DB 008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h ; < + DB 000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h ; = + DB 040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h ; > + DB 078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h ; ? + DB 07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h ; @ + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; A + DB 0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h ; B + DB 078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h ; C + DB 0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h ; D + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h ; E + DB 0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h ; F + DB 078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h ; G + DB 084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h ; H + DB 038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h ; I + DB 01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h ; J + DB 084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h ; K + DB 080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h ; L + DB 0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h ; M + DB 082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h ; N + DB 078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; O + DB 0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h ; P + DB 078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h ; Q + DB 0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h ; R + DB 078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h ; S + DB 0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h ; T + DB 084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h ; U + DB 084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h ; V + DB 082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h ; W + DB 082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h ; X + DB 044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h ; Y + DB 0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h ; Z + DB 078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h ; [ + DB 000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h ; \ + DB 078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h ; ] + DB 010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h ; ^ + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh ; _ + DB 020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h ; ` + DB 000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; a + DB 000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h ; b + DB 000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h ; c + DB 000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h ; d + DB 000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; e + DB 000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h ; f + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h ; g + DB 000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h ; h + DB 000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h ; i + DB 000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h ; j + DB 000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h ; k + DB 000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h ; l + DB 000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h ; m + DB 000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; n + DB 000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; o + DB 000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h ; p + DB 000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h ; q + DB 000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h ; r + DB 000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h ; s + DB 000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h ; t + DB 000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; u + DB 000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h ; v + DB 000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h ; w + DB 000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h ; x + DB 000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; y + DB 000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h ; z + DB 000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h ; { + DB 000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h ; | + DB 000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h ; } + DB 064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h ; ~ + DB 000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h ;  + DB 07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch ; #128 + DB 000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h ; #129 + DB 03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h ; #130 + DB 07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #131 + DB 024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #132 + DB 078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #133 + DB 018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #134 + DB 000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h ; #135 + DB 07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #136 + DB 048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #137 + DB 078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h ; #138 + DB 000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #139 + DB 010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h ; #140 + DB 000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h ; #141 + DB 048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #142 + DB 030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h ; #143 + DB 038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h ; #144 + DB 000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h ; #145 + DB 07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h ; #146 + DB 07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h ; #147 + DB 028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #148 + DB 070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #149 + DB 038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h ; #150 + DB 070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #151 + DB 028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch ; #152 + DB 048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h ; #153 + DB 048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h ; #154 + DB 000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h ; #155 + DB 038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh ; #156 + DB 044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h ; #157 + DB 0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h ; #158 + DB 00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h ; #159 + DB 03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h ; #160 + DB 000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h ; #161 + DB 01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h ; #162 + DB 01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h ; #163 + DB 07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h ; #164 + DB 07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h ; #165 + DB 018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h ; #166 + DB 01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h ; #167 + DB 010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h ; #168 + DB 000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h ; #169 + DB 000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h ; #170 + DB 040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h ; #171 + DB 040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h ; #172 + DB 010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h ; #173 + DB 000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h ; #174 + DB 000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h ; #175 + DB 022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h ; #176 + DB 055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh ; #177 + DB 0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh ; #178 + DB 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h ; #179 + DB 018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h ; #180 + DB 018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #181 + DB 036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h ; #182 + DB 000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h ; #183 + DB 000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h ; #184 + DB 036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h ; #185 + DB 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h ; #186 + DB 000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h ; #187 + DB 036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h ; #188 + DB 036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h ; #189 + DB 018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h ; #190 + DB 000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h ; #191 + DB 018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h ; #192 + DB 018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h ; #193 + DB 000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h ; #194 + DB 018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h ; #195 + DB 000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h ; #196 + DB 018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h ; #197 + DB 018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #198 + DB 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h ; #199 + DB 036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h ; #200 + DB 000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h ; #201 + DB 036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h ; #202 + DB 000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h ; #203 + DB 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h ; #204 + DB 000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #205 + DB 036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h ; #206 + DB 018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h ; #207 + DB 036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h ; #208 + DB 000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h ; #209 + DB 000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h ; #210 + DB 036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h ; #211 + DB 018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h ; #212 + DB 000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h ; #213 + DB 000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h ; #214 + DB 036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h ; #215 + DB 018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h ; #216 + DB 018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h ; #217 + DB 000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h ; #218 + DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh ; #219 + DB 000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh ; #220 + DB 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h ; #221 + DB 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh ; #222 + DB 0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h ; #223 + DB 000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h ; #224 + DB 000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h ; #225 + DB 000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h ; #226 + DB 000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h ; #227 + DB 0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h ; #228 + DB 03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h ; #229 + DB 000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h ; #230 + DB 000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h ; #231 + DB 038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h ; #232 + DB 078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h ; #233 + DB 078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h ; #234 + DB 078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h ; #235 + DB 000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h ; #236 + DB 000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h ; #237 + DB 018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h ; #238 + DB 078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h ; #239 + DB 000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h ; #240 + DB 020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h ; #241 + DB 020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h ; #242 + DB 008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h ; #243 + DB 00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h ; #244 + DB 010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h ; #245 + DB 000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h ; #246 + DB 000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h ; #247 + DB 038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h ; #248 + DB 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h ; #249 + DB 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h ; #250 + DB 00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h ; #251 + DB 038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h ; #252 + DB 03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h ; #253 + DB 000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h ; #254 + DB 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; #255 diff --git a/16/xw__/makefile b/16/xw__/makefile new file mode 100755 index 00000000..cfe15232 --- /dev/null +++ b/16/xw__/makefile @@ -0,0 +1,132 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +!ifdef __LINUX__ +REMOVECOMMAND=rm -f +COPYCOMMAND=cp -f +DIRSEP=/ +OBJ=o +!else +REMOVECOMMAND=del +COPYCOMMAND=copy /y +DIRSEP=\ +OBJ=obj +!endif +LIBINCS = modex.def + +LIBOBJS = mxbb.$(OBJ) mxcc.$(OBJ) mxcg.$(OBJ) mxcl.$(OBJ) mxcr.$(OBJ) mxfb.$(OBJ) mxgc.$(OBJ) mxgi.$(OBJ) mxgm.$(OBJ) mxgp.$(OBJ) mxgv.$(OBJ) mxhl.$(OBJ) mxit.$(OBJ) mxll.$(OBJ) mxln.$(OBJ) mxot.$(OBJ) mxpb.$(OBJ) mxpf.$(OBJ) mxpg.$(OBJ) mxpi.$(OBJ) mxpn.$(OBJ) mxpp.$(OBJ) mxra.$(OBJ) mxrp.$(OBJ) mxsa.$(OBJ) mxsc.$(OBJ) mxsi.$(OBJ) mxsl.$(OBJ) mxsm.$(OBJ) mxsp.$(OBJ) mxss.$(OBJ) mxtl.$(OBJ) mxvs.$(OBJ) mxwd.$(OBJ) mxwm.$(OBJ) mxwp.$(OBJ) mxwr.$(OBJ) +#mxfp.$(OBJ) +# +# ASM compiler +# +ASMC =wasm +ASMO =-mh -0 + +# +# PAS compiler +# +#PASC = tpc +#PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = wlib + +# .asm.obj: +# $(ASMC) $(ASMO) $< + +mxbb.$(OBJ): mxbb.asm + $(ASMC) $(ASMO) mxbb.asm +mxcc.$(OBJ): mxcc.asm + $(ASMC) $(ASMO) mxcc.asm +mxcg.$(OBJ): mxcg.asm + $(ASMC) $(ASMO) mxcg.asm +mxcl.$(OBJ): mxcl.asm + $(ASMC) $(ASMO) mxcl.asm +mxcr.$(OBJ): mxcr.asm + $(ASMC) $(ASMO) mxcr.asm +mxfb.$(OBJ): mxfb.asm + $(ASMC) $(ASMO) mxfb.asm +mxfp.$(OBJ): mxfp.asm + $(ASMC) $(ASMO) mxfp.asm +mxgc.$(OBJ): mxgc.asm + $(ASMC) $(ASMO) mxgc.asm +mxgi.$(OBJ): mxgi.asm + $(ASMC) $(ASMO) mxgi.asm +mxgm.$(OBJ): mxgm.asm + $(ASMC) $(ASMO) mxgm.asm +mxgp.$(OBJ): mxgp.asm + $(ASMC) $(ASMO) mxgp.asm +mxgv.$(OBJ): mxgv.asm + $(ASMC) $(ASMO) mxgv.asm +mxhl.$(OBJ): mxhl.asm + $(ASMC) $(ASMO) mxhl.asm +mxit.$(OBJ): mxit.asm + $(ASMC) $(ASMO) mxit.asm +mxll.$(OBJ): mxll.asm + $(ASMC) $(ASMO) mxll.asm +mxln.$(OBJ): mxln.asm + $(ASMC) $(ASMO) mxln.asm +mxot.$(OBJ): mxot.asm + $(ASMC) $(ASMO) mxot.asm +mxpb.$(OBJ): mxpb.asm + $(ASMC) $(ASMO) mxpb.asm +mxpf.$(OBJ): mxpf.asm + $(ASMC) $(ASMO) mxpf.asm +mxpg.$(OBJ): mxpg.asm + $(ASMC) $(ASMO) mxpg.asm +mxpi.$(OBJ): mxpi.asm + $(ASMC) $(ASMO) mxpi.asm +mxpn.$(OBJ): mxpn.asm + $(ASMC) $(ASMO) mxpn.asm +mxpp.$(OBJ): mxpp.asm + $(ASMC) $(ASMO) mxpp.asm +mxra.$(OBJ): mxra.asm + $(ASMC) $(ASMO) mxra.asm +mxrp.$(OBJ): mxrp.asm + $(ASMC) $(ASMO) mxrp.asm +mxsa.$(OBJ): mxsa.asm + $(ASMC) $(ASMO) mxsa.asm +mxsc.$(OBJ): mxsc.asm + $(ASMC) $(ASMO) mxsc.asm +mxsi.$(OBJ): mxsi.asm + $(ASMC) $(ASMO) mxsi.asm +mxsl.$(OBJ): mxsl.asm + $(ASMC) $(ASMO) mxsl.asm +mxsm.$(OBJ): mxsm.asm + $(ASMC) $(ASMO) mxsm.asm +mxsp.$(OBJ): mxsp.asm + $(ASMC) $(ASMO) mxsp.asm +mxss.$(OBJ): mxss.asm + $(ASMC) $(ASMO) mxss.asm +mxtl.$(OBJ): mxtl.asm + $(ASMC) $(ASMO) mxtl.asm +mxvs.$(OBJ): mxvs.asm + $(ASMC) $(ASMO) mxvs.asm +mxwd.$(OBJ): mxwd.asm + $(ASMC) $(ASMO) mxwd.asm +mxwm.$(OBJ): mxwm.asm + $(ASMC) $(ASMO) mxwm.asm +mxwp.$(OBJ): mxwp.asm + $(ASMC) $(ASMO) mxwp.asm +mxwr.$(OBJ): mxwr.asm + $(ASMC) $(ASMO) mxwr.asm + +all: $(LIBOBJS) modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw__/makefile.bcc b/16/xw__/makefile.bcc new file mode 100755 index 00000000..d3ad8b71 --- /dev/null +++ b/16/xw__/makefile.bcc @@ -0,0 +1,81 @@ +# +# MODEX library makefile (for Borland MAKE) +# Copyright (c) 1993,1994 by Alessandro Scotti +# +LIBINCS = MODEX.DEF + +LIBOBJS = MXBB.OBJ \ + MXCC.OBJ \ + MXCG.OBJ \ + MXCL.OBJ \ + MXCR.OBJ \ + MXFB.OBJ \ + MXFP.OBJ \ + MXGC.OBJ \ + MXGI.OBJ \ + MXGM.OBJ \ + MXGP.OBJ \ + MXGV.OBJ \ + MXHL.OBJ \ + MXIT.OBJ \ + MXLL.OBJ \ + MXLN.OBJ \ + MXOT.OBJ \ + MXPB.OBJ \ + MXPF.OBJ \ + MXPG.OBJ \ + MXPI.OBJ \ + MXPN.OBJ \ + MXPP.OBJ \ + MXRA.OBJ \ + MXRP.OBJ \ + MXSA.OBJ \ + MXSC.OBJ \ + MXSI.OBJ \ + MXSL.OBJ \ + MXSM.OBJ \ + MXSP.OBJ \ + MXSS.OBJ \ + MXTL.OBJ \ + MXVS.OBJ \ + MXWD.OBJ \ + MXWM.OBJ \ + MXWP.OBJ \ + MXWR.OBJ + +# +# ASM compiler +# +ASMC = tasm +ASMO = /m5 /p + +# +# PAS compiler +# +PASC = tpc +PASO = /m -$D- -$L- -$S- + +# +# LIB maker, uses response file +# +LIBC = tlib + +.asm.obj: + $(ASMC) $(ASMO) $< + +target: modex.lib +# modex.tpu modex.tpp + +#modex.tpu: $(LIBOBJS) modex.pas +# $(PASC) $(PASO) modex +# copy modex.tpu .. +# copy modex.pas .. + +#modex.tpp: $(LIBOBJS) modex.pas +# $(PASC) /cp $(PASO) modex +# copy modex.tpp .. + +modex.lib: modex.lbr $(LIBOBJS) + $(LIBC) modex.lib @modex.lbr + +$(LIBOBJS): modex.def diff --git a/16/xw__/modex.bak b/16/xw__/modex.bak new file mode 100755 index 00000000..560a1c68 Binary files /dev/null and b/16/xw__/modex.bak differ diff --git a/16/xw__/modex.def b/16/xw__/modex.def new file mode 100755 index 00000000..7977a4a0 --- /dev/null +++ b/16/xw__/modex.def @@ -0,0 +1,163 @@ +;------------------------------------------------------------ +; +; MODEX.DEF - Include file +; Copyright (c) 1993-1994 by Alessandro Scotti +; +;JUMPS +;LOCALS + +TRUE EQU 1 ; Boolean constants +FALSE EQU 0 + +USE286 = FALSE ; TRUE enables 80286 instructions +USE386 = FALSE ; TRUE enables 80386 (and 80286) instructions + +IF USE286 EQ TRUE + P286 +ENDIF + +IF USE386 EQ TRUE + P386 + USE286 = TRUE +ENDIF + +MXVERSION EQU 0128h ; Library version (1.40) + +;------------------------------------------------------------ +; +; VGA definitions +; +MISC EQU 3C2h ; Miscellaneous output +TS EQU 3C4h ; Timing Sequencer index register +GDC EQU 3CEh ; Graphics Data Controller index register +CRTC EQU 3D4h ; CRTC index register +STATUS EQU 3DAh ; Input Status register one + +;------------------------------------------------------------ +; +; Raster operators +; +OP_SET EQU 0 +OP_MOVE EQU 0 ; Same as OP_SET +OP_AND EQU 1 +OP_OR EQU 2 +OP_XOR EQU 3 +OP_TRANS EQU 4 +OP_ADD EQU 5 ; Must be last op + +;------------------------------------------------------------ +; +; Polygon fill functions +; +POLYSCANBUFSIZE EQU 4*1024 + +;------------------------------------------------------------ +; Macro to push registers, variables or flags onto the stack +; Usage: .push "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.push MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.PUSH has more than 10 arguments> + ENDIF + IRP $reg, + IFB <$reg> ;; Is argument blank? + EXITM ;; Yes, exit + ELSEIFIDNI <$reg>, ;; Is argument the keyword "FLAGS"? + pushf ;; Yes, push flags + ELSE + push $reg ;; Push argument + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; Macro to pop registers, variables or flags from the stack +; Usage: .pop "loc16"[,"loc16"...] +; where "loc16" is a 16-bit register, a word-sized variable or the +; keyword "FLAGS". +; Exmpl: .push ax, flags, var1 +; .pop ax, flags, var1 +; +.pop MACRO r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + IFNB + .ERROR <.POP has more than 10 arguments> + ENDIF + IRP $reg, + IFNB <$reg> ;; Is argument non-blank? + IFIDNI <$reg>, ;; Yes, is it the keyword "FLAGS"? + popf ;; Yes, pop flags + ELSE + pop $reg ;; Pop argument + ENDIF + ENDIF + ENDM +ENDM + +;------------------------------------------------------------ +; +.enter MACRO localsize + IF USE286 EQ TRUE + enter localsize, 0 + ELSE + push bp + mov bp, sp + sub sp, localsize + ENDIF +ENDM + +;------------------------------------------------------------ +; +;.leave MACRO argsize +; IF USE286 EQ TRUE +; leave +; ELSE +; mov sp, bp +; pop bp +; ENDIF +; IFNB +; ret argsize +; ELSE +; ret +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shr MACRO arg, count +; IF USE286 EQ TRUE +; shr arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shr arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.shl MACRO arg, count +; IF USE286 EQ TRUE +; shl arg, count +; ELSE +; $temp = count +; WHILE $temp GT 0 +; shl arg, 1 +; $temp = $temp-1 +; ENDM +; ENDIF +;ENDM + +;------------------------------------------------------------ +; +;.chk386 MACRO name, jump +; IF USE386 EQ FALSE +; .OUT "Warning: ", , " needs a 386 or better to run!" +; jmp @@jump +; ENDIF +;ENDM diff --git a/16/xw__/modex.h b/16/xw__/modex.h new file mode 100755 index 00000000..2c1f1ebe --- /dev/null +++ b/16/xw__/modex.h @@ -0,0 +1,153 @@ +/* + MODEX.H - C/C++ include file for the MODEX library + Copyright (c) 1994 Alessandro Scotti +*/ + +#ifndef _MODEX_H_ // Avoid nested inclusions +#define _MODEX_H_ + +// +// Video modes +// +#define MX_TEXT 0 // 80x25 text +#define MX_320x175 1 // 320x175x256 +#define MX_320x200 2 // 320x200x256, 4 pages, aspect 6:5 +#define MX_320x240 3 // 320x240x256, 3 pages, aspect 1:1 +#define MX_320x350 4 // 320x350x256 +#define MX_320x400 5 // 320x400x256, 2 pages +#define MX_320x480 6 // 320x480x256, 1 page +#define MX_360x175 7 // 360x175x256 +#define MX_360x200 8 // 360x200x256, 3 pages +#define MX_360x240 9 // 360x240x256, 2 pages +#define MX_360x350 10 // 360x350x256 +#define MX_360x400 11 // 360x400x256, 1 page +#define MX_360x480 12 // 360x480x256, 1 page +#define MX_400x600 13 // 400x600x256, 1 page + +// +// Fade effects +// +#define MX_FADEIN 0 +#define MX_FADEOUT 1 + +// +// Raster ops +// +#define OP_SET 0 // No operator +#define OP_AND 1 // And +#define OP_OR 2 // Or +#define OP_XOR 3 // Xor +#define OP_TRANS 4 // Transparent +#define OP_ADD 5 // Additive +#define OP_MOVE 0 // Alias for OP_SET + +// +// Temporary definitions +// +#define MXBYTE unsigned char +#define MXBOOL short int +#define MXSINT short int +#define MXUINT unsigned short int +#define MXAPI far pascal +#define MXPTR void far * + +// Functions + +#ifdef __cplusplus // Avoid C++ name mangling +extern "C" { +#endif + +// +// Initialization +// +MXSINT MXAPI mxInit( void ); // Returns 0 if successful +void MXAPI mxTerm( void ); +MXUINT MXAPI mxGetVersion( void ); +// +// Mode setting +// +void MXAPI mxChangeMode( MXUINT mode ); +void MXAPI mxSetMode( MXUINT mode ); +void MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty ); +void MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height ); +// +// Hardware support +// +void MXAPI mxWriteMode( MXBYTE wm ); +void MXAPI mxSplitScreen( MXUINT line ); +void MXAPI mxStartAddress( MXUINT sa ); +void MXAPI mxStartLine( MXUINT sl ); +void MXAPI mxWaitDisplay( void ); +void MXAPI mxWaitRetrace( void ); +void MXAPI mxWritePlane( MXBYTE wp ); +void MXAPI mxReadPlane( MXBYTE rp ); +void MXAPI mxRowAddress( MXBYTE ra ); +// +// Virtual screen +// +void MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height ); +void MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height ); +void MXAPI mxPan( MXUINT x, MXUINT y ); +// +// Clipping +// +MXBOOL MXAPI mxGetClip( void ); +MXBOOL MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h ); +MXBOOL MXAPI mxSetClip( MXBOOL ); +void MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height ); +// +// Graphics +// +void MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy ); +void MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op ); +MXBYTE MXAPI mxGetPixel( MXSINT x, MXSINT y ); +void MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color ); +void MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op ); +void MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op ); +void MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height ); +void MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h ); +void MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color ); +void MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op ); +// +// Palette +// +void MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count ); +void MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b ); +void MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue ); +void MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count ); +void MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT ); +void MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step ); +// +// Text +// +MXSINT MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight ); +void MXAPI mxSetTextColor( MXUINT color, MXUINT op ); +void MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay ); +void MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay ); +void MXAPI mxOutChar( MXSINT x, MXSINT y, char c ); +void MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz ); +// +// Convex polygons +// +void MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); +void MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT ); + +#ifdef __cplusplus +} +#endif + +// +// Remove temporary defines +// +#undef MXBYTE +#undef MXBOOL +#undef MXSINT +#undef MXUINT +#undef MXPTR +#undef MXAPI + +#endif // _MODEX_H_ diff --git a/16/xw__/modex.lbr b/16/xw__/modex.lbr new file mode 100755 index 00000000..93fc7801 --- /dev/null +++ b/16/xw__/modex.lbr @@ -0,0 +1,39 @@ ++-MXBB.OBJ & ++-MXCC.OBJ & ++-MXCG.OBJ & ++-MXCL.OBJ & ++-MXCR.OBJ & ++-MXFB.OBJ & ++-MXFP.OBJ & ++-MXGC.OBJ & ++-MXGI.OBJ & ++-MXGM.OBJ & ++-MXGP.OBJ & ++-MXGV.OBJ & ++-MXHL.OBJ & ++-MXIT.OBJ & ++-MXLL.OBJ & ++-MXLN.OBJ & ++-MXOT.OBJ & ++-MXPB.OBJ & ++-MXPF.OBJ & ++-MXPG.OBJ & ++-MXPI.OBJ & ++-MXPN.OBJ & ++-MXPP.OBJ & ++-MXPT.OBJ & ++-MXRA.OBJ & ++-MXRP.OBJ & ++-MXSA.OBJ & ++-MXSC.OBJ & ++-MXSI.OBJ & ++-MXSL.OBJ & ++-MXSM.OBJ & ++-MXSP.OBJ & ++-MXSS.OBJ & ++-MXTL.OBJ & ++-MXVS.OBJ & ++-MXWD.OBJ & ++-MXWM.OBJ & ++-MXWP.OBJ & ++-MXWR.OBJ diff --git a/16/xw__/modex.pas b/16/xw__/modex.pas new file mode 100755 index 00000000..7d9d26ed --- /dev/null +++ b/16/xw__/modex.pas @@ -0,0 +1,194 @@ +(* + Turbo Pascal interface to the MODEX library + Copyright (c) 1993,1994 by Alessandro Scotti +*) +unit ModeX; +interface + +const + (* Video modes *) + MX_TEXT = 0; + MX_320x175 = 1; + MX_320x200 = 2; + MX_320x240 = 3; + MX_320x350 = 4; + MX_320x400 = 5; + MX_320x480 = 6; + MX_360x175 = 7; + MX_360x200 = 8; + MX_360x240 = 9; + MX_360x350 = 10; + MX_360x400 = 11; + MX_360x480 = 12; + MX_400x600 = 13; + + (* Fade effects *) + MX_FADEIN = 0; + MX_FADEOUT = 1; + + (* Raster ops *) + OP_SET = 0; + OP_AND = 1; + OP_OR = 2; + OP_XOR = 3; + OP_TRANS = 4; + OP_ADD = 5; + OP_MOVE = 0; (* Alias for OP_SET *) + +procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer ); +procedure mxCircle( CX, CY: integer; Radius: word; Color: byte ); +procedure mxChangeMode( Mode: word ); +procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word ); +procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word ); +procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word ); +procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word ); +procedure mxGetAspect( var AspectX, AspectY: word ); +function mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean; +function mxGetClip: boolean; +procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word ); +procedure mxGetPalette( Palette: pointer; Start, Count: word ); +function mxGetPixel( X, Y: word ): byte; +procedure mxGetScreenSize( var Width, Height: word ); +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); +function mxGetVersion: word; +procedure mxGetVirtualScreen( var Width, Height: word ); +procedure mxInit; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); +procedure mxOutChar( X, Y: integer; C: char ); +procedure mxOutText( X, Y: integer; S: pointer ); +procedure mxPan( X, Y: word ); +procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word ); +procedure mxPutPixel( X, Y: word; C: byte ); +procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxReadPlane( Plane: byte ); +procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer ); +procedure mxRowAddress( RowAddress: byte ); +function mxSetClip( Clip: boolean ): boolean; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); +procedure mxSetColor( Index, R, G, B: word ); +procedure mxSetFont( Font: pointer; Width, Height: word ); +procedure mxSetMode( Mode: word ); +procedure mxSetPalette( Palette: pointer; Start, Count: word ); +procedure mxSetTextColor( Color, Op: word ); +procedure mxSetTextStep( DeltaX, DeltaY: integer ); +procedure mxSetVirtualScreen( Width, Height: word ); +procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word ); +procedure mxSplitScreen( Line: word ); +procedure mxStartAddress( StartAddress: word ); +procedure mxStartLine( Line: word ); +procedure mxTerm; +procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word ); +procedure mxWaitDisplay; +procedure mxWaitRetrace; +procedure mxWriteMode( Mode: byte ); +procedure mxWritePlane( Plane: byte ); + +procedure mxFillPoly( Count: word; var Map, Points; Color: word ); +procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word ); +procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word ); + +procedure mxOutStr( X, Y: integer; S: string ); + +implementation + +procedure mxBitBlt; external; +procedure mxChangeMode( Mode: word ); external; +procedure mxCircle; external; +procedure mxColorToGray; external; +procedure mxFadePalette; external; +procedure mxFillBox; external; +procedure mxGammaCorrect; external; +procedure mxGetAspect( var AspectX, AspectY: word ); external; +function mxGetClipRegion; external; +function mxGetClip: boolean; external; +procedure mxGetImage; external; +procedure mxGetPalette( Palette: pointer; Start, Count: word ); external; +function mxGetPixel( X, Y: word ): byte; external; +procedure mxGetScreenSize( var Width, Height: word ); external; +procedure mxGetTextStep( var DeltaX, DeltaY: integer ); external; +function mxGetVersion: word; external; +procedure mxGetVirtualScreen( var Width, Height: word ); external; +procedure mxInit; external; +procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word ); external; +procedure mxOutChar( X, Y: integer; C: char ); external; +procedure mxOutText( X, Y: integer; S: pointer ); external; +procedure mxPan( X, Y: word ); external; +procedure mxPutImage; external; +procedure mxPutPixel( X, Y: word; C: byte ); external; +procedure mxPutTile; external; +procedure mxReadPlane( Plane: byte ); external; +procedure mxRotatePalette; external; +procedure mxRowAddress( RowAddress: byte ); external; +function mxSetClip( Clip: boolean ): boolean; external; +procedure mxSetClipRegion( X1, Y1, Width, Height: word ); external; +procedure mxSetColor( Index, R, G, B: word ); external; +procedure mxSetFont( Font: pointer; Width, Height: word ); external; +procedure mxSetMode( Mode: word ); external; +procedure mxSetPalette( Palette: pointer; Start, Count: word ); external; +procedure mxSetTextColor( Color, Op: word ); external; +procedure mxSetTextStep( DeltaX, DeltaY: integer ); external; +procedure mxSetVirtualScreen( Width, Height: word ); external; +procedure mxSplitScreen( Line: word ); external; +procedure mxStartAddress( StartAddress: word ); external; +procedure mxStartLine; external; +procedure mxStretchImage; external; +procedure mxTerm; external; +procedure mxTransPutTile; external; +procedure mxWaitDisplay; external; +procedure mxWaitRetrace; external; +procedure mxWriteMode( Mode: byte ); external; +procedure mxWritePlane( Plane: byte ); external; + +procedure mxFillPoly; external; +procedure mxGouraudPoly; external; +procedure mxTexturePoly; external; +{$L MXPB} +{$L MXPF} +{$L MXPG} +{$L MXPT} + +{$L MXBB} +{$L MXCC} +{$L MXCG} +{$L MXCL} +{$L MXCR} +{$L MXFB} +{$L MXFP} +{$L MXGI} +{$L MXGM} +{$L MXGP} +{$L MXGV} +{$L MXHL} +{$L MXIT} +{$L MXLN} +{$L MXOT} +{$L MXPI} +{$L MXPN} +{$L MXPP} +{$L MXRA} +{$L MXRP} +{$L MXSA} +{$L MXSC} +{$L MXSI} +{$L MXSL} +{$L MXSM} +{$L MXSP} +{$L MXSS} +{$L MXTL} +{$L MXVS} +{$L MXWD} +{$L MXWM} +{$L MXWP} +{$L MXWR} + +(* + Prints a Turbo Pascal string. + Note: BP 7.0 supports ASCIIZ strings (PChar type). +*) +procedure mxOutStr; +begin + S := S + #0; + mxOutText( X, Y, @S[1] ); +end; + +end. diff --git a/16/xw__/modex/DEMO01.EXE b/16/xw__/modex/DEMO01.EXE new file mode 100755 index 00000000..28caff88 Binary files /dev/null and b/16/xw__/modex/DEMO01.EXE differ diff --git a/16/xw__/modex/DEMO01.PAS b/16/xw__/modex/DEMO01.PAS new file mode 100755 index 00000000..c684acdd --- /dev/null +++ b/16/xw__/modex/DEMO01.PAS @@ -0,0 +1,126 @@ +(* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + MAX_SPRITE = 100; +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO02.EXE b/16/xw__/modex/DEMO02.EXE new file mode 100755 index 00000000..14e7dc72 Binary files /dev/null and b/16/xw__/modex/DEMO02.EXE differ diff --git a/16/xw__/modex/DEMO02.PAS b/16/xw__/modex/DEMO02.PAS new file mode 100755 index 00000000..6b4fb6f9 --- /dev/null +++ b/16/xw__/modex/DEMO02.PAS @@ -0,0 +1,125 @@ +(* + DEMO02 - Texture mapping and palette rotation + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Plasma, Threed; + +const + LSIZE = 85; + Trans : TPoint = ( X:0; Y:0; Z:0 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of T2DPoint; + Width : word; + Data : array[ 1..64*64 ] of byte; + end; + TQuad = record + VtxCnt : word; + Vtx : array[ 0..3 ] of word; + Texture: word; + end; +var + Vtx : array[ 0..7 ] of TPoint; + XVtx : array[ 0..7 ] of TPoint; + VVtx : array[ 0..7 ] of T2DPoint; + Face : array[ 0..5 ] of TQuad; + Txts : array[ 0..5 ] of TTexture; + Nrm : array[ 0..5 ] of TPoint; + XNrm : array[ 0..5 ] of TPoint; + Page : word; + Palette: array[ byte ] of record R, G, B: byte; end; + +(* Make a 64x64 plasma to be used as texture *) +procedure MakeTexture( Idx: word ); +var + I: word; +begin + mxFillBox( 0, 0, 64, 64, 0, OP_SET ); + MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 ); + mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 ); + (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *) + with Txts[Idx] do begin + Desc[0].X := $80; Desc[0].Y := $80; + Desc[1].X := $80; Desc[1].Y := $3F80; + Desc[2].X := $3F80; Desc[2].Y := $3F80; + Desc[3].X := $3F80; Desc[3].Y := $80; + Width := 64; + end; +end; + +procedure Init; +var + I: integer; +begin + (* Build vertexes for a cube *) + with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end; + with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end; + with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end; + with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end; + for I:=0 to 7 do begin (* Make points 16:16 fixed *) + Vtx[I].X := Vtx[I].X*$10000; + Vtx[I].Y := Vtx[I].Y*$10000; + Vtx[I].Z := Vtx[I].Z*$10000; + end; + (* Build faces *) + with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end; + with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end; + with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end; + with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end; + with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end; + with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end; + for I:=0 to 5 do Face[I].Texture := I; + (* Build textures and palette *) + Randomize; + FillChar( Palette, SizeOf(Palette), 0 ); + MakePlasmaPalette( Palette, PAL_RGB ); + mxSetPalette( @Palette, 0, 193 ); + for I:=0 to 5 do MakeTexture( I ); +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, 8 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + mxRotatePalette( @Palette[1], 192, 3 ); (* Rotate palette *) + (* Draw cube: backface culling is straighforward in this case, so *) + (* it can be handled by the polygon filling procedure *) + for I:=0 to 5 do + mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width ); + mxStartLine( Page ); (* Flip pages *) + mxSetPalette( @Palette[1], 1, 192 ); (* Set new palette *) + Page := 240-Page; + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO03.EXE b/16/xw__/modex/DEMO03.EXE new file mode 100755 index 00000000..c646c4b0 Binary files /dev/null and b/16/xw__/modex/DEMO03.EXE differ diff --git a/16/xw__/modex/DEMO03.PAS b/16/xw__/modex/DEMO03.PAS new file mode 100755 index 00000000..01d10f49 --- /dev/null +++ b/16/xw__/modex/DEMO03.PAS @@ -0,0 +1,152 @@ +(* + DEMO03 - Simple star animation, morphs between a cube and a sphere + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 1000; (* Number of points *) + EDGE = 70; (* Length of cube edge *) + RADIUS = 90; (* Radius of sphere *) + WAITCOUNT = 192; (* Frames to wait for non-morphing shapes *) + MS = 32; (* Number of steps for morphing *) + Trans : TPoint = ( X:0; Y:0; Z:0 ); + InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 ); + InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS ); + InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 ); + InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 ); +type + T2DPoint = record + X, Y: integer; + end; + T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint; + P3DPointArray = ^T3DPointArray; +var + CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray; + VVtx : array[ 0..MAXVTX-1 ] of T2DPoint; + Page : word; + Status, Count, Delta1, Delta2, Morph1, Morph2: integer; + +procedure Swap( var A, B: longint ); +var + L: longint; +begin + L := A; A := B; B := L; +end; + +function Toggle( A: longint ): longint; +begin + Toggle := A; + if( Random(2) = 0 ) then Toggle := -A; +end; + +procedure Init; +label Retry; +var + I: integer; +begin + New( CubeVtx ); + New( SphereVtx ); + New( Vtx ); + New( XVtx ); + (* Build vertexes (yes, I know this piece of code is terrible) *) + Randomize; + for I:=0 to MAXVTX-1 do begin + with CubeVtx^[I] do begin + (* Build cube *) + X := (longint(Random(2*EDGE))-EDGE)*$10000; + Y := (longint(Random(2*EDGE))-EDGE)*$10000; + Z := Toggle( EDGE*$10000 ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + end; + with SphereVtx^[I] do begin + (* Build sphere *) +Retry: + X := (longint(Random(2*RADIUS))-RADIUS); + Y := (longint(Random(2*RADIUS))-RADIUS); + if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry; + Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) ); + case Random(3) of + 0: Swap( X, Z ); + 1: Swap( Y, Z ); + end; + X := X * $10000; Y := Y * $10000; Z := Z * $10000; + end; + end; + (* Initialize morphing *) + Move( CubeVtx^, Vtx^, SizeOf(Vtx^) ); + Status := 0; + Count := WAITCOUNT; +end; + +procedure Morph; +var + I: integer; +begin + (* Fully unoptimized, slowest loop I could think of! *) + for I:=0 to MAXVTX-1 do begin + Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS; + Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS; + Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS; + end; +end; + +var + AX, AY, AZ: byte; + I: word; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + C := #0; + repeat + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx^, XVtx^, MAXVTX ); (* 3D transform points *) + tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 1 ); + Inc( AZ, 2 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw points *) + for I:=0 to MAXVTX-1 do + mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 ); + mxStartLine( Page ); (* Flip pages *) + Page := 240-Page; + (* Morph *) + if( Odd(Status) ) then begin + Morph; + Inc( Morph1, Delta1 ); + Inc( Morph2, Delta2 ); + if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status ); + if( Status = 4 ) then Status := 0; + end + else begin + Dec( Count ); + if( Count < 0 ) then begin + Inc( Status ); + Count := WAITCOUNT; + Morph1 := InitMorph1[Status]; + Morph2 := InitMorph2[Status]; + Delta1 := InitDelta1[Status]; + Delta2 := InitDelta2[Status]; + end; + end; + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO04.DAT b/16/xw__/modex/DEMO04.DAT new file mode 100755 index 00000000..72aaad08 Binary files /dev/null and b/16/xw__/modex/DEMO04.DAT differ diff --git a/16/xw__/modex/DEMO04.EXE b/16/xw__/modex/DEMO04.EXE new file mode 100755 index 00000000..1fec5e8a Binary files /dev/null and b/16/xw__/modex/DEMO04.EXE differ diff --git a/16/xw__/modex/DEMO04.PAS b/16/xw__/modex/DEMO04.PAS new file mode 100755 index 00000000..1a946315 --- /dev/null +++ b/16/xw__/modex/DEMO04.PAS @@ -0,0 +1,198 @@ +(* + DEMO04 - Multiple textures and triple buffering (3 pages) + (c) 1994 by Alessandro Scotti +*) +uses Crt, Modex, Threed; + +const + MAXVTX = 256; + MAXCUB = 2; + MAXTXT = 2; + Trans : TPoint = ( X:0; Y:0; Z:0 ); + TxtSunDial: array[ 0..7 ] of word = ( + $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 ); + TxtSapphire : array[ 0..7 ] of word = ( + $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 ); + TxtMarble: array[ 0..7 ] of word = ( + $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 ); +type + T2DPoint = record + X, Y: integer; + end; + TTexture = record + Desc : array[ 0..3 ] of record X, Y: word end; + Width : word; + Data : pointer; + end; + TQuad = record + Vtx : array[ 0..3 ] of word; + Texture: word; + end; + TCube = record + Face : array[ 0..5 ] of TQuad; + Base : integer; + end; +var + Vtx, XVtx: array[ 0..MAXVTX ] of TPoint; + VVtx : array[ 0..MAXVTX ] of T2DPoint; + Cube : array[ 0..MAXCUB ] of TCube; + ZList : array[ 0..MAXCUB ] of integer; + VtxCnt : word; + Txts : array[ 0..MAXTXT ] of TTexture; + Page : word; + Palette : array[ byte ] of record R, G, B: byte; end; + TxtDat1, TxtDat2: pointer; + +(* Add a new entry to the vertex array *) +procedure AddVtx( PX, PY, PZ: longint ); +begin + with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end; + Inc( VtxCnt ); +end; + +procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer ); +const + FaceIdx: array[ 0..23 ] of integer = ( + 0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 ); +var + I, VC: integer; +begin + VC := VtxCnt; + C.Base := VC; + AddVtx( X1+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y1+TY, Z1+TZ ); + AddVtx( X2+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y2+TY, Z1+TZ ); + AddVtx( X1+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y1+TY, Z2+TZ ); + AddVtx( X2+TX, Y2+TY, Z2+TZ ); + AddVtx( X1+TX, Y2+TY, Z2+TZ ); + for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I]; + for I:=0 to 5 do C.Face[I].Texture := Texture; +end; + +procedure MakeTexture( Idx: integer; var VtxData ); +var + P: ^word; + I: integer; +begin + P := @VtxData; + with Txts[Idx] do begin + for I:=0 to 3 do begin + Desc[I].X := P^; Inc( P ); + Desc[I].Y := P^; Inc( P ); + end; + Width := 129; + Data := TxtDat1; + end; +end; + +procedure Init; +var + I: integer; + V: integer; + F: file; + P: array[ 1..768 ] of byte; +begin + (* Initialize objects *) + VtxCnt := 0; + MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 ); (* Sundial *) + Cube[0].Face[0].Texture := 0; + V := VtxCnt; + MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *) + tdSetTranslation( Trans ); + tdSetRotation( 32, 32, 00 ); + tdRotate( Vtx[V], XVtx[V], 8 ); (* Got to rotate this cube *) + for I:=V to V+7 do begin + Vtx[I].X := XVtx[I].X; + Vtx[I].Y := XVtx[I].Y; + Vtx[I].Z := XVtx[I].Z + 100*$10000; + end; + MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *) + (* Load texture and palette *) + Assign( F, 'DEMO04.DAT' ); + Reset( F, 1 ); + BlockRead( F, P, SizeOf(P) ); + mxSetPalette( @P, 0, 256 ); + GetMem( TxtDat1, 63*1024 ); + BlockRead( F, TxtDat1^, 129*286 ); + Close( F ); + TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 ); + (* Init textures *) + MakeTexture( 0, TxtSundial ); + MakeTexture( 1, TxtMarble ); + MakeTexture( 2, TxtSapphire ); + Txts[2].Data := TxtDat2; +end; + +(* Sort procedure, not worth optimizing with only a few objects *) +procedure SortObjects; +var + I, J, K: integer; + ZMax: array[ 0..MAXCUB ] of longint; + ZI: integer; + L: longint; +begin + for I:=0 to MAXCUB do begin + L := XVtx[Cube[I].Base].Z; + for J:=1 to 7 do + if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z; + ZMax[I] := L; + ZList[I] := I; + end; + for I:=0 to MAXCUB-1 do begin + ZI := I; + for J:=I+1 to MAXCUB do + if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J; + if( ZI <> I ) then begin + K := ZList[I]; + ZList[I] := ZList[ZI]; + ZList[ZI] := K; + end; + end; +end; + +var + AX, AY, AZ: byte; + I, J, K: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + (* Init 3D transforms, perspective is intentionally exaggerated *) + AX := 0; AY := 0; AZ := 0; + tdSetTranslation( Trans ); + tdSetPerspective( 600*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, VtxCnt ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 1 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw objects *) + SortObjects; + for I:=0 to MAXCUB do with Cube[ZList[I]] do begin + for J:=0 to 5 do begin + K := Face[J].Texture; + mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width ); + end; + end; + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* If the frame rate seems low, try to remove this line *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO05.EXE b/16/xw__/modex/DEMO05.EXE new file mode 100755 index 00000000..21a7c207 Binary files /dev/null and b/16/xw__/modex/DEMO05.EXE differ diff --git a/16/xw__/modex/DEMO05.PAS b/16/xw__/modex/DEMO05.PAS new file mode 100755 index 00000000..819c5cf3 --- /dev/null +++ b/16/xw__/modex/DEMO05.PAS @@ -0,0 +1,131 @@ +(* + DEMO05 - A Gouraud-shaded rotating torus + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex, Threed; + +(* Define ALTPAL for alternate palette *) +{$define ALTPAL} + +const + MAXVTX1 = 15; RADIUS1 = 70; (* MAXVTX1+1 must be multiple of 4 *) + MAXVTX2 = 15; RADIUS2 = 30; + MAXVTX = (MAXVTX1+1)*(MAXVTX2+1)-1; + MAXFACE = MAXVTX; + Trans : TPoint = ( X:0; Y:0; Z:0 ); (* Object translation *) + Light : TPoint = ( X:0; Y:0; Z:-63*$10000 ); (* Light direction *) +type + TQuad = record + QVtx : array[ 0..3 ] of integer; + end; +var + Vtx, XVtx : array[ 0..MAXVTX ] of TPoint; (* Points *) + VVtx : array[ 0..MAXVTX ] of record X, Y: integer end; + Face : array[ 0..MAXFACE ] of TQuad; (* Polys *) + Culled : array[ 0..MAXFACE ] of integer; + GNrm,XGNrm: array[ 0..MAXVTX ] of TVector; (* Gouraud normals *) + VtxLight : array[ 0..MAXVTX ] of integer; (* Points brightness *) + Page : word; + +function GetVtx( I1, I2: integer ): integer; +begin + GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1); +end; + +procedure Init; +var + R, N, X, Y, Z: real; + I, J, K, V: integer; +begin + (* Build vertexes *) + for I:=0 to MAXVTX1 do begin + K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1); + R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) ); + for J:=0 to MAXVTX2 do begin + V := I*(MAXVTX2+1)+J; (* Index of current vertex *) + (* Compute coordinates of current vertex *) + X := R*Cos(2*J*Pi / (MAXVTX2+1)); (* Get coordinates *) + Y := R*Sin(2*J*Pi / (MAXVTX2+1)); + Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1)); + Vtx[V].X := Round( X )*$10000; (* Save coordinates *) + Vtx[V].Y := Round( Y )*$10000; + Vtx[V].Z := Round( Z )*$10000; + (* Compute direction of Gouraud normal thru current vertex *) + X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1)); + Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1)); + N := Sqrt( X*X + Y*Y + Z*Z ); (* Get vector length *) + GNrm[V].X := Trunc( X*$10000/N ); (* Save normal vector *) + GNrm[V].Y := Trunc( Y*$10000/N ); + GNrm[V].Z := Trunc( Z*$10000/N ); + end; + end; + (* Generate faces so that depth-sorting is not needed: there are still *) + (* some *very* little errors, but this is the best I could devise *) + J := 0; + K := 0; + for I:=0 to MAXFACE do with Face[I] do begin + QVtx[0] := GetVtx( J, K ); + QVtx[1] := GetVtx( J, K+1 ); + QVtx[2] := GetVtx( J+1, K+1 ); + QVtx[3] := GetVtx( J+1, K ); + Inc( K ); + if( K > MAXVTX2 ) then begin + K := 0; + Inc( J ); + end; + end; +{$ifndef ALTPAL} + for I:=0 to 63 do mxSetColor( I+64, 0, 0, I ); (* Blue palette *) +{$else} + for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *) + for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 ); +{$endif} +end; + +var + AX, AY, AZ: byte; + I: word; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; (* Start with hidden page *) + + AX := 0; + AY := 0; + AZ := 0; + (* Init 3D transforms, perspective is intentionally exaggerated *) + tdSetTranslation( Trans ); + tdSetLight( Light ); + tdSetPerspective( 400*$10000, $10000, $10000 ); + (* Main loop, all magic here! *) + while( not KeyPressed ) do begin + tdSetRotation( AX, AY, AZ ); (* Set new angles *) + tdTransform( Vtx, XVtx, MAXVTX+1 ); (* 3D transform points *) + tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page ); + tdRotate( GNrm, XGNrm, MAXVTX+1 ); (* Rotate Gouraud normals *) + tdTransformLight( XGNrm, VtxLight, MAXVTX+1 ); + (* Backplane culling is not really needed here! *) + FillChar( Culled, SizeOf(Culled), 0 ); + tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) ); + Inc( AX, 1 ); (* Bump angles *) + Inc( AY, 2 ); + Inc( AZ, 3 ); + mxSetClipRegion( 0, Page, 320, 240 ); (* Set clip to new page *) + mxSetClip( TRUE ); + mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *) + (* Draw polygons *) + for I:=0 to MAXFACE do with Face[I] do + if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 ); + (* Flip page: at 320x240 the Start Address Register Low is always zero *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 480; end; + 480: begin PortW[$3D4] := $960C; Page := 0; end; + end; + mxWaitRetrace; (* Uncomment this instruction if screen flickers *) + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO06.DAT b/16/xw__/modex/DEMO06.DAT new file mode 100755 index 00000000..1ac2c2bb Binary files /dev/null and b/16/xw__/modex/DEMO06.DAT differ diff --git a/16/xw__/modex/DEMO06.EXE b/16/xw__/modex/DEMO06.EXE new file mode 100755 index 00000000..f1308e8a Binary files /dev/null and b/16/xw__/modex/DEMO06.EXE differ diff --git a/16/xw__/modex/DEMO06.PAS b/16/xw__/modex/DEMO06.PAS new file mode 100755 index 00000000..f26af067 --- /dev/null +++ b/16/xw__/modex/DEMO06.PAS @@ -0,0 +1,135 @@ +(* + DEMO06 - Magnifying glass + (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + R = 40; (* Lens radius *) + K : real = 1.8; (* Magnifying factor, less makes a stronger lens *) +type + TLine = array[ 0..319 ] of byte; + PLine = ^TLine; + TScreen = array[ 0..239 ] of PLine; +var + VScreen: TScreen; (* Virtual screen *) + BallX : array[ 0..R, 0..R ] of integer; + BallY : array[ 0..R, 0..R ] of integer; + Sprite : array[ -R..R, -R..R ] of byte; + Page : word; + +(* Returns "lens-view" coordinates of X,Y *) +procedure GetCoords( var X, Y: integer ); +var + LR, Z, SinA, SinB, TgB, Q: real; +begin + LR := Sqrt( X*X + Y*Y ); + if( LR = 0 ) then Exit; + if( LR < R ) then begin + Z := Sqrt( R*R - LR*LR ); + SinA := LR / R; + SinB := SinA / K; + TgB := SinB / Sqrt( 1-SinB*SinB ); + Q := LR - TgB*Z; + X := Round( X * ( Q/LR ) ); + Y := Round( Y * ( Q/LR ) ); + end; +end; + +procedure Init; +var + F : file; + Palette: array[ 0..767 ] of record R, G, B: byte; end; + X, Y, + X2, Y2 : integer; +begin + (* Load background image *) + Assign( F, 'demo06.dat' ); + Reset( F, 1 ); + BlockRead( F, Palette, 768 ); + mxSetPalette( @Palette, 0, 256 ); + for Y:=0 to 239 do begin + New( VScreen[Y] ); + BlockRead( F, VScreen[Y]^, 320 ); + mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE ); + end; + Close( F ); + (* Build lens *) + for X:=0 to R do begin + for Y:=0 to R do begin + X2 := X; + Y2 := Y; + GetCoords( X2, Y2 ); + BallX[X, Y] := X2; + BallY[X, Y] := Y2; + end; + end; +end; + +procedure PutLens( OX, OY: integer ); +var + X, Y: integer; +begin + for X:=0 to R do begin + for Y:=0 to R do begin + Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ]; + Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ]; + end; + end; + (* Draw the sprite *) + mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE ); +end; + +function Delta: integer; +begin + Delta := Random(3)+2; +end; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*Delta; + end; +end; + +var + X, Y, DX, DY: integer; + C: char; +begin + mxInit; + mxSetMode( MX_320x240 ); + Init; + Page := 240; + X := R; + Y := R; + Randomize; + DX := Delta; + DY := Delta; + + (* Main loop *) + repeat + (* Update video *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + PutLens( X, Y ); + mxCircle( X, Page+Y, R, 0 ); + (* Update lens coordinates *) + Inc( X, DX ); + Check( X+R >= 319, X, DX, 319-R, -1 ); + Check( X <= R, X, DX, R, +1 ); + Inc( Y, DY ); + Check( Y+R >= 239, Y, DY, 239-R, -1 ); + Check( Y <= R, Y, DY, R, +1 ); + (* Flip pages: double buffering, avoid wait for display *) + case Page of + 0 : begin PortW[$3D4] := $000C; Page := 240; end; + 240: begin PortW[$3D4] := $4B0C; Page := 0; end; + end; + mxWaitRetrace; (* Wait for hidden page to show *) + until( KeyPressed ); + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/DEMO07.EXE b/16/xw__/modex/DEMO07.EXE new file mode 100755 index 00000000..8a401169 Binary files /dev/null and b/16/xw__/modex/DEMO07.EXE differ diff --git a/16/xw__/modex/DEMO07.PAS b/16/xw__/modex/DEMO07.PAS new file mode 100755 index 00000000..04fff790 --- /dev/null +++ b/16/xw__/modex/DEMO07.PAS @@ -0,0 +1,68 @@ +(* + DEMO07 - Hardware scrolling + Copyright (c) 1994 Alessandro Scotti +*) +uses Crt, Modex; + +const + (* Change this if scrolling seems jerky (this simple program does *) + (* not handle vertical retrace/display very well) *) + STEPS = 5; + +procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer ); +begin + if( Cond ) then begin + Coord := NewCoord; + DeltaC := Sign*(Random(3)+2); + end; +end; + +var + I, X, Y, DX, DY: integer; +begin + (* Initialize library and graphics mode *) + mxInit; + mxSetMode( MX_320x200 ); + (* Set a 640x400 virtual screen *) + mxSetVirtualScreen( 640, 400 ); + mxSetClip( TRUE ); + + X := 0; + Y := 0; + DX := 1; + DY := 1; + + (* Main loop: draw lines, circles, points and rectangles in separate *) + (* 320x200 windows, while smoothly panning virtual screen *) + while( not KeyPressed ) do begin + (* Points *) + mxSetClipRegion( 0, 0, 320, 200 ); + for I:=1 to STEPS do + mxPutPixel( Random(320), Random(200), Random(16) ); + (* Lines *) + mxSetClipRegion( 0, 200, 320, 200 ); + for I:=1 to STEPS do + mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET ); + (* Circles *) + mxSetClipRegion( 320, 0, 320, 200 ); + for I:=1 to STEPS do + mxCircle( Random(320)+320, Random(200), Random(100), Random(16) ); + (* Boxes *) + mxSetClipRegion( 320, 200, 320, 200 ); + for I:=1 to STEPS do + mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET ); + (* Pan *) + Inc( X, DX ); + Check( X+320 >= 639, X, DX, 319, -1 ); + Check( X < 0, X, DX, 0, +1 ); + Inc( Y, DY ); + Check( Y+200 >= 399, Y, DY, 199, -1 ); + Check( Y < 0, Y, DY, 0, +1 ); + mxPan( X, Y ); + mxWaitRetrace; + end; + + (* Shutdown *) + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/MATH.INC b/16/xw__/modex/MATH.INC new file mode 100755 index 00000000..742af410 --- /dev/null +++ b/16/xw__/modex/MATH.INC @@ -0,0 +1,34 @@ +; +; MATH.INC - Include file for THREED.ASM +; + +; 3-dimensional point, coordinates in fixed format (16:16) +; +TPOINT STRUC + X DD ? + Y DD ? + Z DD ? +TPOINT ENDS + +; 2-dimensional point, coordinates in integer format +; +TIMAGEPOINT STRUC + IX DW ? + IY DW ? +TIMAGEPOINT ENDS + +; Fixed-point divide: EAX = EAX / arg +; +.xdiv MACRO arg + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv arg +ENDM + +; Fixed-point multiply: EAX = EAX * arg +; +.xmul MACRO arg + imul arg + shrd eax, edx, 16 +ENDM diff --git a/16/xw__/modex/PLASMA.PAS b/16/xw__/modex/PLASMA.PAS new file mode 100755 index 00000000..237e292a --- /dev/null +++ b/16/xw__/modex/PLASMA.PAS @@ -0,0 +1,103 @@ +unit Plasma; +interface + +const + PAL_RGB = 0; + PAL_CLOUDS = 1; + PAL_LANDSCAPE = 2; + +procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte ); +procedure MakePlasmaPalette( var Palette; What: word ); + +implementation uses Modex; + +procedure NewColor( XA, YA, X, Y, XB, YB: integer ); +var + Color: longint; +begin + Color := Abs( XA-XB )+Abs( YA-YB ); + Color := Random( Color shl 1 )-Color; + Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1; + if( Color < 1 ) then Color := 1; + if( Color > 192 ) then Color := 192; + if( mxGetPixel( X, Y ) = 0 ) then + mxPutPixel( X, Y, Lo(Color) ); +end; + +procedure Divide( X1, Y1, X2, Y2: integer ); +var + X, Y, Color: integer; +begin + if not( (X2-X1<2)and(Y2-Y1<2) ) then begin + X := (X1+X2) shr 1; + Y := (Y1+Y2) shr 1; + NewColor( X1, Y1, X, Y1, X2, Y1 ); + NewColor( X2, Y1, X2, Y, X2, Y2 ); + NewColor( X1, Y2, X, Y2, X2, Y2 ); + NewColor( X1, Y1, X1, Y, X1, Y2 ); + Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+ + mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2; + mxPutPixel( X, Y, Color ); + Divide( X1, Y1, X, Y ); + Divide( X, Y1, X2, Y ); + Divide( X, Y, X2, Y2 ); + Divide( X1, Y, X, Y2 ); + end; +end; + +procedure MakePlasma; +begin + Dec( W ); + Dec( H ); + mxPutPixel( X, Y, C1 ); + mxPutPixel( X, Y+H, C2 ); + mxPutPixel( X+W, Y+H, C3 ); + mxPutPixel( X+W, Y, C4 ); + Divide( X, Y, X+W, Y+H ); +end; + +procedure MakePlasmaPalette; +type + TPal = array[ byte ] of record R, G, B: byte end; +var + I: word; +begin + FillChar( TPal(Palette)[1], 192*3, 0 ); + case What of + PAL_CLOUDS: + for I:=1 to 192 do begin + TPal(Palette)[I].R := Abs( I-96 )*63 div 96; + TPal(Palette)[I].G := Abs( I-96 )*63 div 96; + TPal(Palette)[I].B := 63; + end; + PAL_LANDSCAPE: + begin + for I:=0 to 31 do begin + TPal(Palette)[I+1].R := I; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := I + I shr 1+15; + end; + for I:=32 to 63 do begin + TPal(Palette)[I+1].R := 0; + TPal(Palette)[I+1].G := I; + TPal(Palette)[I+1].B := 0; + end; + for I:=64 to 191 do begin + TPal(Palette)[I+1].R := (I-64) div 3 + 15; + TPal(Palette)[I+1].G := (I-64) div 3 + 15; + TPal(Palette)[I+1].B := (I-64) div 3 + 15; + end; + end; + else + for I:=1 to 64 do begin + TPal(Palette)[I].G := I-1; + TPal(Palette)[I].B := 64-I; + TPal(Palette)[I+64].R := I-1; + TPal(Palette)[I+64].G := 64-I; + TPal(Palette)[I+128].B := I-1; + TPal(Palette)[I+128].R := 64-I; + end; + end; +end; + +end. \ No newline at end of file diff --git a/16/xw__/modex/QIX2.EXE b/16/xw__/modex/QIX2.EXE new file mode 100755 index 00000000..a10d7db5 Binary files /dev/null and b/16/xw__/modex/QIX2.EXE differ diff --git a/16/xw__/modex/QIX2.PAS b/16/xw__/modex/QIX2.PAS new file mode 100755 index 00000000..d1b59791 --- /dev/null +++ b/16/xw__/modex/QIX2.PAS @@ -0,0 +1,210 @@ +{$E-,N+} +uses Crt, Modex; + +const + DEFVERT = 12; (* Vertex count *) + DEFREPL = 3; (* Repetition count *) + DEFQIXS = 2; (* Qixs *) + FADESPEED = 48; +type + TPoint = record + X, Y : integer; + end; + TRGB = record + R, G, B: byte; + end; + TQix = record + Color: integer; + Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint; + Delta: array[ 0..DEFVERT-1 ] of TPoint; + end; +var + Page : integer; + MaxX, + MaxY : word; + Qix : array[ 0..DEFQIXS-1 ] of TQix; + Pal : array[ byte ] of TRGB; + +type + TReal = double; + TRPoint = record + X, Y: TReal; + end; + TMatrix = array[ 0..3, 0..3 ] of TReal; +var + M: TMatrix; + G: array[ 0..DEFVERT-1 ] of TRPoint; + C: array[ 0..DEFVERT-1 ] of TRPoint; + +procedure BumpPal( Idx, DR, DG, DB, Steps: integer ); +var + I: integer; +begin + for I:=1 to Steps do begin + Pal[Idx+1].R := Pal[Idx].R + DR; + Pal[Idx+1].G := Pal[Idx].G + DG; + Pal[Idx+1].B := Pal[Idx].B + DB; + Inc( Idx ); + end; +end; + +procedure InitPalette; +begin + with Pal[0] do begin R:=0; G:=0; B:=0; end; + with Pal[1] do begin R:=0; G:=0; B:=62; end; + BumpPal( 1, 0, 2, -2, 31 ); + BumpPal( 32, 2, -2, 0, 31 ); + BumpPal( 63, -2, 2, 2, 31 ); + BumpPal( 94, 2, 0, -2, 31 ); + BumpPal( 125, -2, -2, 2, 31 ); +end; + +procedure Init( var Qix: TQix; Color: integer ); +var + I: integer; +begin + FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 ); + for I:=0 to DEFVERT-1 do begin + Qix.Vert[I, DEFREPL-1].X := Random( MaxX ); + Qix.Vert[I, DEFREPL-1].Y := Random( MaxY ); + Qix.Delta[I].X := Random(5)+1; + Qix.Delta[I].Y := Random(5)+1; + end; + Qix.Color := Color; + + (* Initialize matrix (Catmull-Rom) *) + M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2; + M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2; + M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0; + M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0; +end; + +procedure mxBezier( var Qix: TQix; I0, Idx, N: integer ); +var + I, J: integer; + T, T2, T3: TReal; + X0, Y0, X, Y: TReal; + Delta: TReal; +begin + (* Compute coefficients *) + for I:=0 to 3 do begin + C[I].X := 0; + for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X; + C[I].Y := 0; + for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y; + end; + X0 := C[3].X; + Y0 := C[3].Y; + Delta := 1 / N; + T := 0; + for I:=1 to N do begin + T := T + Delta; + T2 := T*T; + T3 := T*T2; + X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X; + Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y; + mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET ); + X0 := X; + Y0 := Y; + end; +end; + +procedure Plot( var Qix: TQix; Idx: integer ); +var + I, J: integer; +begin + for I:=0 to DEFVERT-1 do begin + mxBezier( Qix, I, Idx, 12 ); + end; +end; + +procedure Update( var Qix: TQix; Idx: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Inc( Vert[I,Idx].X, Delta[I].X ); + if( Vert[I,Idx].X < 0 ) then begin + Vert[I,Idx].X := 0; + Delta[I].X := Random( 5 )+1; + end; + if( Vert[I,Idx].X > MaxX ) then begin + Vert[I,Idx].X := MaxX; + Delta[I].X := -Random( 5 )-1; + end; + Inc( Vert[I,Idx].Y, Delta[I].Y ); + if( Vert[I,Idx].Y < 0 ) then begin + Vert[I,Idx].Y := 0; + Delta[I].Y := Random( 5 )+1; + end; + if( Vert[I,Idx].Y > MaxY ) then begin + Vert[I,Idx].Y := MaxY; + Delta[I].Y := -Random( 5 )-1; + end; + end; +end; + +procedure Copy( var Qix: TQix; Dest, Src: integer ); +var + I: integer; +begin + for I:=0 to DEFVERT-1 do with Qix do begin + Vert[I,Dest].X := Vert[I,Src].X; + Vert[I,Dest].Y := Vert[I,Src].Y; + end; +end; + +procedure AnimateQix; +var + Q, Idx, I, J, P, Count: integer; +begin + Count := 0; + P := DEFREPL-1; + I := 0; + J := 1; + repeat + mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 ); + mxSetClip( TRUE ); + mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET ); + for Q:=0 to DEFQIXS-1 do begin + Copy( Qix[Q], I, P ); + Update( Qix[Q], I ); + for Idx:=0 to DEFREPL-1 do begin + Plot( Qix[Q], Idx ); + end; + end; + I := (I+1) mod DEFREPL; + J := (J+1) mod DEFREPL; + P := (P+1) mod DEFREPL; + Inc( Count ); + mxStartLine( Page ); + if( Count >= FADESPEED ) then begin + for Q:=0 to DEFQIXS-1 do begin + Inc( Qix[Q].Color ); + if( Qix[Q].Color > 156 ) then + Qix[Q].Color := 1; + end; + Count := 0; + end; + Page := 240-Page; + until( KeyPressed ); +end; + +var + I: integer; +begin + Randomize; + mxInit; + mxSetMode( MX_320x240 ); + mxGetScreenSize( MaxX, MaxY ); + for I:=0 to DEFQIXS-1 do + Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 ); + InitPalette; + mxSetPalette( @Pal, 0, 157 ); + Page := 240; + Dec( MaxX ); + Dec( MaxY ); + AnimateQix; + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/modex/README.TXT b/16/xw__/modex/README.TXT new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw__/modex/README.TXT @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw__/modex/SINCOS.INC b/16/xw__/modex/SINCOS.INC new file mode 100755 index 00000000..6986eeeb --- /dev/null +++ b/16/xw__/modex/SINCOS.INC @@ -0,0 +1,518 @@ +; +; SINCOS.INC - Sin/cos tables for THREED.ASM +; + +tblSin LABEL DWORD + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 +tblCos LABEL DWORD + DD 16777216 + DD 16772163 + DD 16757007 + DD 16731757 + DD 16696429 + DD 16651044 + DD 16595628 + DD 16530216 + DD 16454846 + DD 16369565 + DD 16274424 + DD 16169479 + DD 16054795 + DD 15930439 + DD 15796488 + DD 15653022 + DD 15500126 + DD 15337895 + DD 15166424 + DD 14985817 + DD 14796184 + DD 14597637 + DD 14390298 + DD 14174291 + DD 13949745 + DD 13716797 + DD 13475586 + DD 13226258 + DD 12968963 + DD 12703856 + DD 12431097 + DD 12150850 + DD 11863283 + DD 11568571 + DD 11266890 + DD 10958422 + DD 10643353 + DD 10321873 + DD 9994176 + DD 9660458 + DD 9320922 + DD 8975771 + DD 8625213 + DD 8269459 + DD 7908725 + DD 7543226 + DD 7173184 + DD 6798821 + DD 6420363 + DD 6038037 + DD 5652074 + DD 5262706 + DD 4870169 + DD 4474698 + DD 4076531 + DD 3675909 + DD 3273072 + DD 2868265 + DD 2461729 + DD 2053710 + DD 1644455 + DD 1234209 + DD 823219 + DD 411733 + DD 0 + DD -411733 + DD -823219 + DD -1234209 + DD -1644455 + DD -2053710 + DD -2461729 + DD -2868265 + DD -3273072 + DD -3675909 + DD -4076531 + DD -4474698 + DD -4870169 + DD -5262706 + DD -5652074 + DD -6038037 + DD -6420363 + DD -6798821 + DD -7173184 + DD -7543226 + DD -7908725 + DD -8269459 + DD -8625213 + DD -8975771 + DD -9320922 + DD -9660458 + DD -9994176 + DD -10321873 + DD -10643353 + DD -10958422 + DD -11266890 + DD -11568571 + DD -11863283 + DD -12150850 + DD -12431097 + DD -12703856 + DD -12968963 + DD -13226258 + DD -13475586 + DD -13716797 + DD -13949745 + DD -14174291 + DD -14390298 + DD -14597637 + DD -14796184 + DD -14985817 + DD -15166424 + DD -15337895 + DD -15500126 + DD -15653022 + DD -15796488 + DD -15930439 + DD -16054795 + DD -16169479 + DD -16274424 + DD -16369565 + DD -16454846 + DD -16530216 + DD -16595628 + DD -16651044 + DD -16696429 + DD -16731757 + DD -16757007 + DD -16772163 + DD -16777216 + DD -16772163 + DD -16757007 + DD -16731757 + DD -16696429 + DD -16651044 + DD -16595628 + DD -16530216 + DD -16454846 + DD -16369565 + DD -16274424 + DD -16169479 + DD -16054795 + DD -15930439 + DD -15796488 + DD -15653022 + DD -15500126 + DD -15337895 + DD -15166424 + DD -14985817 + DD -14796184 + DD -14597637 + DD -14390298 + DD -14174291 + DD -13949745 + DD -13716797 + DD -13475586 + DD -13226258 + DD -12968963 + DD -12703856 + DD -12431097 + DD -12150850 + DD -11863283 + DD -11568571 + DD -11266890 + DD -10958422 + DD -10643353 + DD -10321873 + DD -9994176 + DD -9660458 + DD -9320922 + DD -8975771 + DD -8625213 + DD -8269459 + DD -7908725 + DD -7543226 + DD -7173184 + DD -6798821 + DD -6420363 + DD -6038037 + DD -5652074 + DD -5262706 + DD -4870169 + DD -4474698 + DD -4076531 + DD -3675909 + DD -3273072 + DD -2868265 + DD -2461729 + DD -2053710 + DD -1644455 + DD -1234209 + DD -823219 + DD -411733 + DD 0 + DD 411733 + DD 823219 + DD 1234209 + DD 1644455 + DD 2053710 + DD 2461729 + DD 2868265 + DD 3273072 + DD 3675909 + DD 4076531 + DD 4474698 + DD 4870169 + DD 5262706 + DD 5652074 + DD 6038037 + DD 6420363 + DD 6798821 + DD 7173184 + DD 7543226 + DD 7908725 + DD 8269459 + DD 8625213 + DD 8975771 + DD 9320922 + DD 9660458 + DD 9994176 + DD 10321873 + DD 10643353 + DD 10958422 + DD 11266890 + DD 11568571 + DD 11863283 + DD 12150850 + DD 12431097 + DD 12703856 + DD 12968963 + DD 13226258 + DD 13475586 + DD 13716797 + DD 13949745 + DD 14174291 + DD 14390298 + DD 14597637 + DD 14796184 + DD 14985817 + DD 15166424 + DD 15337895 + DD 15500126 + DD 15653022 + DD 15796488 + DD 15930439 + DD 16054795 + DD 16169479 + DD 16274424 + DD 16369565 + DD 16454846 + DD 16530216 + DD 16595628 + DD 16651044 + DD 16696429 + DD 16731757 + DD 16757007 + DD 16772163 diff --git a/16/xw__/modex/THREED.ASM b/16/xw__/modex/THREED.ASM new file mode 100755 index 00000000..5ecd3ba3 --- /dev/null +++ b/16/xw__/modex/THREED.ASM @@ -0,0 +1,872 @@ +COMMENT / + Fixed-point math functions and 3D transforms + Copyright (c) 1993,94 by Alessandro Scotti +/ +WARN PRO +P386 +JUMPS +LOCALS + +INCLUDE MATH.INC + +PUBLIC tdFixedMul +PUBLIC tdGetNormal +PUBLIC tdRotate +PUBLIC tdGetSurfaceLight +PUBLIC tdSetLight +PUBLIC tdSetRotation +PUBLIC tdSetTranslation +PUBLIC tdTransform +PUBLIC tdTransformToImage +PUBLIC tdTransformLight +PUBLIC tdBackPlaneCull +PUBLIC tdSetPerspective + +;----------------------------------------------------------- +; +; Data segment +; +MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' + ASSUME ds:MATH_DATA + +INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table + +XRotation TPOINT <> ; 3x3 rotation matrix +YRotation TPOINT <> +ZRotation TPOINT <> + +Translation TPOINT <> ; Translation vector + +Light TPOINT <> ; Light vector +AmbientLight DW 00 ; Ambient light + +XScale DD 10000h ; Scaling factor for X coordinate +YScale DD 10000h ; Scaling factor for Y coordinate +PerspectiveDistance DD 20000000h + +MATH_DATA ENDS + +;----------------------------------------------------------- +; +; Code segment +; +MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING + +tdSetPerspective PROC PASCAL FAR + ARG Perspective:DWORD, \ + ScaleX:DWORD, \ + ScaleY:DWORD + USES ds + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov eax, [Perspective] + mov [PerspectiveDistance], eax + mov eax, [ScaleX] + mov [XScale], eax + mov eax, [ScaleY] + mov [YScale], eax + + ret +tdSetPerspective ENDP + + +;----------------------------------------------------------- +; +; Sets the rotation matrix. +; +; Input: +; RX = X-axis rotation angle +; RY = X-axis rotation angle +; RZ = X-axis rotation angle +; Output: +; none +; +tdSetRotation PROC PASCAL FAR + ARG RX:WORD, \ + RY:WORD, \ + RZ:WORD + USES ds, si, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + mov bx, [RZ] + mov si, [RY] + mov di, [RX] + shl bx, 2 + shl si, 2 + shl di, 2 + + push ebp ; We use EBP as a scratch register + +; Set X rotation + mov eax, tblCos[bx] + imul tblCos[si] + mov [XRotation.X], edx + + mov eax, tblSin[bx] + imul tblCos[si] + mov [XRotation.Y], edx + + mov eax, tblSin[si] + sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 + mov [XRotation.Z], eax + +; Set Y rotation + mov eax, tblCos[bx] + imul tblSin[si] ; EDX:EAX = fixed 16:48 + shrd eax, edx, 24 ; EAX = fixed 8:24 + imul tblSin[di] ; EDX:EAX = fixed 16:48 + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblCos[di] + add eax, ebp + adc edx, ecx ; EDX:EAX = fixed 16:48 + neg edx + mov [YRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblSin[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblCos[di] + sub eax, ebp + sbb edx, ecx + mov [YRotation.Y], edx + + mov eax, tblCos[si] + imul tblSin[di] + mov [YRotation.Z], edx + +; Set Z rotation + mov eax, tblCos[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblSin[bx] + imul tblSin[di] + sub eax, ebp + sbb edx, ecx + mov [ZRotation.X], edx + + mov eax, tblSin[bx] + imul tblSin[si] + shrd eax, edx, 24 + imul tblCos[di] + mov ebp, eax + mov ecx, edx + mov eax, tblCos[bx] + imul tblSin[di] + add eax, ebp + add edx, ecx + neg edx + mov [ZRotation.Y], edx + + mov eax, tblCos[si] + imul tblCos[di] + mov [ZRotation.Z], edx + + pop ebp ; Restore EBP + + ret +tdSetRotation ENDP + +;----------------------------------------------------------- +; +; Sets the translation vector. +; +; Input: +; TV = pointer to translation vector +; Output: +; none +; +tdSetTranslation PROC PASCAL FAR + ARG TV:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [TV] + mov eax, es:[di].X + mov [Translation.X], eax + mov eax, es:[di].Y + mov [Translation.Y], eax + mov eax, es:[di].Z + mov [Translation.Z], eax + + ret +tdSetTranslation ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdTransform PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + LOCAL Adjust:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + + ALIGN DWORD +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + mov ebx, eax + shrd eax, edx, 16 + add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) + mov es:[di].Z, eax +; Get perspective factor + mov ebx, [PerspectiveDistance] + sub eax, ebx + neg eax ; EAX = PD - Z + xor edx, edx + shld edx, eax, 16 + shl eax, 16 + idiv ebx ; EAX = fixed 16:16 result + mov [Adjust], eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.X] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + add eax, [Translation.Y] + imul [Adjust] + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdTransform ENDP + +;----------------------------------------------------------- +; +; Transforms an array of TPOINT into an array of TIMAGEPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TIMAGEPOINT +; Count = number of entries to transform +; DeltaX = translation distance for the X coordinate +; DeltaY = translation distance for the Y coordinate +; Output: +; the maximum Z value +; +tdTransformToImage PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD, \ + DeltaX:WORD, \ + DeltaY:WORD + LOCAL Adjust:DWORD, \ + Max:DWORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + mov [Max], 80000000h + +@@Loop: +; Check max Z + mov eax, fs:[si].Z + cmp eax, [Max] + jle @@1 + mov [Max], eax +@@1: + +; Transform X coordinate + mov ax, WORD PTR fs:[si].X[2] + add ax, [DeltaX] + mov es:[di].IX, ax + +; Transform Y coordinate + mov ax, WORD PTR fs:[si].Y[2] + add ax, [DeltaY] + mov es:[di].IY, ax + + add si, SIZE TPOINT + add di, SIZE TIMAGEPOINT + dec [Count] + jnz @@Loop + + mov eax, [Max] + shld edx, eax, 16 + ret +tdTransformToImage ENDP + +;----------------------------------------------------------- +; +; Sets the light source. +; +; Input: +; Light = pointer to light vector +; Output: +; none +; +tdSetLight PROC PASCAL FAR + ARG L:DWORD + USES ds, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [L] + mov eax, es:[di].X + mov [Light.X], eax + mov eax, es:[di].Y + mov [Light.Y], eax + mov eax, es:[di].Z + mov [Light.Z], eax + + ret +tdSetLight ENDP + +;----------------------------------------------------------- +; +; Computes light intensity for an array of surfaces. +; +; Input: +; Normals = pointer to an array of surface normals +; Lights = pointer to an array of integer to be filled with +; light intensity +; Count = number of elements to transform +; Output: +; none +; +tdTransformLight PROC PASCAL FAR + ARG Normals:DWORD, \ + Lights:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov fs, ax + ASSUME fs:MATH_DATA + + lds si, [Normals] + les di, [Lights] + ASSUME ds:NOTHING + +; Intensity is given by the dot product between the Light vector and +; the surface normal +@@Loop: + mov eax, ds:[si].Z + imul [Light.Z] + mov ebx, eax + mov ecx, edx + mov eax, ds:[si].Y + imul [Light.Y] + add ebx, eax + adc ecx, edx + mov eax, ds:[si].X + imul [Light.X] + add eax, ebx + adc edx, ecx ; EDX:EAX = fixed 32:32 intensity + add dx, [AmbientLight] + test dx, dx + jg @@1 + xor dx, dx ; Return 0 for no light +@@1: + mov es:[di], dx + inc di + inc di + add si, SIZE TPOINT + dec [Count] + jnz @@Loop + + ASSUME fs:NOTHING + ret +tdTransformLight ENDP + +;----------------------------------------------------------- +; +; Returns the light value given the normal to a surface. +; +; Input: +; Normal = pointer to TPOINT surface normal vector +; Output: +; AX = light intensity (>=0) +; Notes: +; the normal is rotated according to the current setting. +; +tdGetSurfaceLight PROC PASCAL FAR + ARG Normal:DWORD + USES ds, esi, es, di + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + les di, [Normal] + +; Transform Z coordinate + mov eax, es:[di].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.Z] + shrd eax, edx, 16 + mov esi, eax + +; Transform X coordinate + mov eax, es:[di].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add esi, eax + +; Transform Y coordinate + mov eax, es:[di].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, es:[di].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, es:[di].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + imul [Light.X] + shrd eax, edx, 16 + add eax, esi + shr eax, 16 + +; Add ambient light + add ax, [AmbientLight] + test ax, ax + jge @@Exit + xor ax, ax + +@@Exit: + ret +tdGetSurfaceLight ENDP + +;----------------------------------------------------------- +; +; Rotates an array of TPOINT. +; +; Input: +; Source = pointer to source array of TPOINT +; Dest = pointer to destination array of TPOINT +; Count = number of entries to transform +; Output: +; none +; +tdRotate PROC PASCAL FAR + ARG Source:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + + mov ax, SEG MATH_DATA + mov ds, ax + ASSUME ds:MATH_DATA + + lfs si, [Source] + les di, [Dest] + +@@Loop: +; Transform Z coordinate + mov eax, fs:[si].X + imul [ZRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [ZRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [ZRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Z, eax + +; Transform X coordinate + mov eax, fs:[si].X + imul [XRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [XRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [XRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].X, eax + +; Transform Y coordinate + mov eax, fs:[si].X + imul [YRotation.X] + mov ecx, eax + mov ebx, edx + mov eax, fs:[si].Y + imul [YRotation.Y] + add ecx, eax + adc ebx, edx + mov eax, fs:[si].Z + imul [YRotation.Z] + add eax, ecx + adc edx, ebx + shrd eax, edx, 16 + mov es:[di].Y, eax + + add si, SIZE TPOINT + add di, SIZE TPOINT + dec [Count] + jnz @@Loop + + ret +tdRotate ENDP + +tdFixedMul PROC PASCAL FAR + ARG F1:DWORD, \ + F2:DWORD + + mov eax, [F1] + imul [F2] + shr eax, 16 + + ret +tdFixedMul ENDP + +;----------------------------------------------------------- +; +; Returns in EAX the square root of EDX:EAX. +; +subSqrt PROC NEAR + push esi + push edi + + add eax, eax + adc edx, 0 + mov eax, edx ; Just discard the low bits + + mov esi, eax + xor edi, edi + shld edi, esi, 16 + shl esi, 16 +@@Loop: + mov ebx, eax + mul eax + add eax, esi + adc edx, edi + shrd eax, edx, 1 + shr edx, 1 + div ebx + cmp eax, ebx + jne @@Loop + +; Adjust EAX + shl eax, 8 + + pop edi + pop esi + ret +subSqrt ENDP + +;----------------------------------------------------------- +; +; Finds the unitary normal to a given surface. +; +; Input: +; Dest = pointer to TPOINT (vector) result +; P1, P2, P3 = pointer to TPOINT points on surface +; Output: +; none +; Notes: +; the normal is given by the cross-product between (P3-P1) and +; (P2-P1), so its orientation depends on the parameters order. +; +tdGetNormal PROC PASCAL FAR + ARG Dest:DWORD, \ + P1:DWORD, \ + P2:DWORD, \ + P3:DWORD + LOCAL V1:TPOINT, \ + V2:TPOINT, \ + N:TPOINT + USES ds, si, es, di + +; Get vector V1 + lds si, [P1] + les di, [P3] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V1.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V1.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V1.Z], eax + +; Get vector V2 + les di, [P2] + mov eax, es:[di].X + sub eax, ds:[si].X + mov [V2.X], eax + mov eax, es:[di].Y + sub eax, ds:[si].Y + mov [V2.Y], eax + mov eax, es:[di].Z + sub eax, ds:[si].Z + mov [V2.Z], eax + +; Get normal vector (V1 x V2) + mov eax, [V1.Z] + imul [V2.Y] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Y] + imul [V2.Z] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.X], eax + + mov eax, [V1.X] + imul [V2.Z] + mov ebx, eax + mov ecx, edx + mov eax, [V1.Z] + imul [V2.X] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Y], eax + + mov eax, [V1.Y] + imul [V2.X] + mov ebx, eax + mov ecx, edx + mov eax, [V1.X] + imul [V2.Y] + sub eax, ebx + sbb edx, ecx + shrd eax, edx, 16 + mov [N.Z], eax + +; Get normal length + mov eax, [N.X] + imul eax + mov ebx, eax + mov ecx, edx + mov eax, [N.Y] + imul eax + add ebx, eax + adc ecx, edx + mov eax, [N.Z] + imul eax + add eax, ebx + adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z + call subSqrt ; EAX = normal length + mov ebx, eax + +; Adjust vector and save it + les di, [Dest] + mov eax, [N.X] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].X, eax + mov eax, [N.Y] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Y, eax + mov eax, [N.Z] + cdq + shld edx, eax, 16 + shl eax, 16 + idiv ebx + mov es:[di].Z, eax + + ret +tdGetNormal ENDP + +TPOLY STRUC + Vtx DW 4 DUP(?) +TPOLY ENDS + +;----------------------------------------------------------- +; +; Performs surface removal on an array of polygons. +; +; Input: +; Poly = pointer to an array of TPOLY +; Vertex = pointer to an array of TPOINT +; Dest = pointer to an array of integer +; Count = number of polygons to check +; Step = size of TPOLY structure +; Output: +; if the n-th polygon is invisible the n-th entry of the +; Dest array is set to -1, other entries are not modified +; (so it's possible to use the Light array for Dest, because +; the light intensity is always >= 0) +; +tdBackPlaneCull PROC PASCAL FAR + ARG Step:WORD, \ + Poly:DWORD, \ + Vertex:DWORD, \ + Dest:DWORD, \ + Count:WORD + USES ds, si, es, di, fs + ASSUME ds:NOTHING + + mov ds, WORD PTR Vertex[2] + les di, [Poly] + mov fs, WORD PTR Dest[2] + +@@Loop: + mov ax, es:[di].Vtx[2] ; Index of 2nd vertex + shl ax, 2 + mov bx, ax + shl ax, 1 + add bx, ax ; BX = index*SIZE TPOINT + add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex + mov ax, es:[di].Vtx[4] ; Index of 3rd vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex + mov ecx, ds:[si].X + sub ecx, ds:[bx].X ; ECX = V3.X-V2.X + mov edx, ds:[si].Y + sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y + mov ax, es:[di].Vtx[0] ; Index of 1st vertex + shl ax, 2 + mov si, ax + shl ax, 1 + add si, ax + add si, WORD PTR [Vertex] ; SI = offset of 1st vertex + mov eax, ds:[si].X + sub eax, ds:[bx].X ; EAX = V1.X-V2.X + mov esi, ds:[si].Y + sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y + imul edx + mov ebx, eax + xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) + mov eax, esi + imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) + sub eax, ebx + sbb edx, ecx + jl @@Next ; Polygon is visible + mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry + mov WORD PTR fs:[bx], -1 ; Remove polygon +@@Next: + add WORD PTR [Dest], 2 ; Next entry for dest + add di, [Step] ; Next polygon + dec [Count] + jnz @@Loop + + ret +tdBackPlaneCull ENDP + +MATH_TEXT ENDS +END diff --git a/16/xw__/modex/THREED.H b/16/xw__/modex/THREED.H new file mode 100755 index 00000000..b993ef86 --- /dev/null +++ b/16/xw__/modex/THREED.H @@ -0,0 +1,32 @@ +typedef struct { + long x, y, z; +} TVECTOR; + +#define PVECTOR TVECTOR far * + +#define TPOINT TVECTOR +#define PPOINT PVECTOR + +#define VPTR void far * + +#ifdef __cplusplus +extern "C" { +#endif + +long far pascal tdFixedMul( long, long ); +int far pascal tdGetSurfaceLight( PPOINT ); +long far pascal tdTransformToImage( VPTR, VPTR, short, short, short ); + +void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short ); +void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT ); +void far pascal tdRotate( VPTR, VPTR, short ); +void far pascal tdSetLight( PVECTOR ); +void far pascal tdSetRotation( short, short, short ); +void far pascal tdSetTranslation( PVECTOR ); +void far pascal tdSetPerspective( long, long, long ); +void far pascal tdTransform( VPTR, VPTR, short ); +void far pascal tdTransformLight( VPTR, VPTR, short ); + +#ifdef __cplusplus +} +#endif diff --git a/16/xw__/modex/THREED.PAS b/16/xw__/modex/THREED.PAS new file mode 100755 index 00000000..8b712c9d --- /dev/null +++ b/16/xw__/modex/THREED.PAS @@ -0,0 +1,40 @@ +unit ThreeD; +interface + +type + TVector = record + X, Y, Z : longint; + end; + TPoint = TVector; + +function tdFixedMul( F1, F2: longint ): longint; +function tdGetSurfaceLight( var Normal: TPoint ): integer; +function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint; + +procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word ); +procedure tdGetNormal( var Dest, P1, P2, P3: TVector ); +procedure tdRotate( var Source, Dest; Count: word ); +procedure tdSetLight( var Light: TVector ); +procedure tdSetRotation( RX, RY, RZ: word ); +procedure tdSetTranslation( var TV: TVector ); +procedure tdSetPerspective( PD, XF, YF: longint ); +procedure tdTransform( var Source, Dest; Count: word ); +procedure tdTransformLight( var Source, Dest; Count: word ); + +implementation + +function tdGetSurfaceLight; external; +procedure tdSetRotation( RX, RY, RZ: word ); external; +procedure tdGetNormal; external; +procedure tdSetTranslation( var TV: TVector ); external; +procedure tdTransform( var Source, Dest; Count: word ); external; +procedure tdRotate; external; +function tdTransformToImage; external; +procedure tdSetLight( var Light: TVector ); external; +procedure tdSetPerspective; external; +procedure tdTransformLight; external; +function tdFixedMul( F1, F2: longint ): longint; external; +procedure tdBackPlaneCull; external; +{$L THREED} + +end. diff --git a/16/xw__/modex/demo01.c b/16/xw__/modex/demo01.c new file mode 100755 index 00000000..0908fdf4 --- /dev/null +++ b/16/xw__/modex/demo01.c @@ -0,0 +1,125 @@ +/* + DEMO01 - Sprites, page flipping and palette rotation + Copyright (c) 1994 Alessandro Scotti +*/ +uses Crt, Modex; + +#DEFINE MAX_SPRITE 100 +type + (* Sprite structure *) + TSprite = record + X, Y : integer; (* Sprite coordinates *) + DX,DY: integer; (* Deltas for sprite movement *) + W, H : integer; (* Sprite width and height *) + Image: array[ 1..16, 1..16 ] of byte; (* Sprite image data *) + end; + (* RGB color structure *) + TRgb = record + R, G, B: byte; + end; +var + S : array[ 1..MAX_SPRITE ] of TSprite; (* An array of sprites *) + Palette: array[ byte ] of TRgb; (* Palette *) + Page : word; (* Page offset *) + I : word; + +(* Initializes a sprite structure *) +procedure sxInit( var S: TSprite ); +var + I: word; +begin + S.X := Random( 320 ); (* Initialize position with random values *) + S.Y := Random( 240 ); + S.DX := Random( 7 )-3; (* Initialize speed with random values *) + S.DY := Random( 7 )-3; + S.W := 16; (* Size is fixed in this program *) + S.H := 16; + (* The image is a square with a hole inside *) + FillChar( S.Image, SizeOf(S.Image), Random(15)+1 ); + for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 ); +end; + +(* Moves a sprite *) +procedure sxMove( var S: TSprite ); +begin + Inc( S.X, S.DX ); (* Get new position *) + Inc( S.Y, S.DY ); + (* Check sprite position, change delta if needed *) + if( S.X > 320 ) then begin + S.X := 320; + S.DX := -S.DX; + end; + if( S.X < -16 ) then begin + S.X := -16; + S.DX := -S.DX; + end; + if( S.Y > 240 ) then begin + S.Y := 240; + S.DY := -S.DY; + end; + if( S.Y < -16 ) then begin + S.Y := -16; + S.DY := -S.DY; + end; + (* Draw the sprite, note the Page offset added to the *) + (* Y coordinate of the image *) + mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS ); +end; + +begin + (* Initialize library *) + mxInit; + + (* Enter graphics mode *) + mxSetMode( MX_320x240 ); + + (* Print initialization message *) + mxSetTextColor( 15, OP_TRANS ); + mxOutStr( 4, 4, 'Initializing...' ); + + (* Initialize sprites *) + for I:=1 to MAX_SPRITE do sxInit( S[I] ); + + (* Draw background *) + for I:=1 to 192 do begin + mxCircle( 160, 480+120, I, I+63 ); + mxCircle( 161, 480+120, I, I+63 ); + end; + + (* Compute and set palette *) + for I:=1 to 192 do with Palette[I+63] do begin + R := 0; + G := 0; + B := 0; + if( I < 64 ) then + R := I shr 1+31 + else if( I < 128 ) then + G := (I-64) shr 1+31 + else + B := (I-128) shr 1+31; + end; + mxSetPalette( @Palette[64], 64, 192 ); + + (* Main loop *) + Page := 240; + while( not KeyPressed ) do begin + (* Set clip region to current page *) + mxSetClipRegion( 0, Page, 320, 240 ); + mxSetClip( TRUE ); + (* Restore background *) + mxBitBlt( 0, 480, 320, 240, 0, Page ); + (* Draw sprites *) + for I:=1 to MAX_SPRITE do sxMove( S[I] ); + (* Print message *) + mxOutStr( 4, Page+4, 'Some sprites moving...' ); + (* Flip page *) + mxStartLine( Page ); + Page := 240-Page; + (* Animate palette *) + mxSetPalette( @Palette[64], 64, 192 ); + mxRotatePalette( @Palette[64], 192, 3 ); + end; + + mxSetMode( MX_TEXT ); + mxTerm; +end. diff --git a/16/xw__/mxbb.asm b/16/xw__/mxbb.asm new file mode 100755 index 00000000..a403c631 --- /dev/null +++ b/16/xw__/mxbb.asm @@ -0,0 +1,208 @@ +.387 + PUBLIC MXBITBLT + EXTRN SUBHORIZONTALLINEINFO:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXBITBLT: + push bp + mov bp,sp + sub sp,16H + push ds + push si + push es + push di + cmp word ptr 0cH[bp],0 + je L$2 + mov ax,word ptr 10H[bp] + and al,3 + mov dx,word ptr 8[bp] + and dl,3 + mov bx,offset L$10 + cmp al,dl + jne L$1 + mov bx,offset L$3 +L$1: + call bx +L$2: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +L$3: + mov bx,word ptr 8[bp] + mov ax,word ptr 6[bp] + mov cx,word ptr 0cH[bp] + call near ptr MX_TEXT:SUBHORIZONTALLINEINFO + mov byte ptr -14H[bp],al + mov byte ptr -16H[bp],ah + mov word ptr 0cH[bp],cx + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov es,ax + mov ax,word ptr 0eH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov si,word ptr 10H[bp] + shr si,1 + shr si,1 + add si,ax + mov dx,3ceH + mov ax,4105H + out dx,ax + cld + mov ah,byte ptr -14H[bp] + or ah,ah + je L$5 + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + dec ax + mov cx,word ptr 0aH[bp] + push si + push di +L$4: + movsb + add si,ax + add di,ax + dec cx + jne L$4 + pop di + pop si + inc si + inc di +L$5: + mov bx,word ptr 0cH[bp] + test bx,bx + je L$7 + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + sub ax,bx + mov dx,word ptr 0aH[bp] + push si + push di +L$6: + mov cx,bx + rep movsb + add si,ax + add di,ax + dec dx + jne L$6 + pop di + pop si + add si,bx + add di,bx +L$7: + mov ah,byte ptr -16H[bp] + or ah,ah + je L$9 + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr cs:MX_BYTESPERLINE + dec ax + mov cx,word ptr 0aH[bp] +L$8: + movsb + add si,ax + add di,ax + dec cx + jne L$8 +L$9: + mov dx,3ceH + mov ax,4005H + out dx,ax + ret +L$10: + mov cx,word ptr 0cH[bp] + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov si,6 +L$11: + mov word ptr -8[bp+si],bx + shr al,1 + adc bx,0 + dec si + dec si + jge L$11 + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov es,ax + mov ax,word ptr 0eH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov si,word ptr 10H[bp] + shr si,1 + shr si,1 + add si,ax + mov word ptr -0aH[bp],si + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 8[bp] + shr di,1 + shr di,1 + add di,ax + mov word ptr -0cH[bp],di + mov ax,word ptr 10H[bp] + and al,3 + mov byte ptr -10H[bp],al + mov cx,word ptr 8[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -12H[bp],al + cld + mov byte ptr -0eH[bp],4 + lea bx,-8[bp] +L$12: + cmp word ptr ss:[bx],0 + je L$15 + mov ah,byte ptr -12H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -10H[bp] + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 0aH[bp] + mov ax,word ptr cs:MX_BYTESPERLINE + sub ax,word ptr ss:[bx] +L$13: + mov cx,word ptr ss:[bx] + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + add si,ax + add di,ax + dec dx + jne L$13 + inc bx + inc bx + inc byte ptr -10H[bp] + and byte ptr -10H[bp],3 + jne L$14 + inc word ptr -0aH[bp] +L$14: + rol byte ptr -12H[bp],1 + adc word ptr -0cH[bp],0 + mov si,word ptr -0aH[bp] + mov di,word ptr -0cH[bp] + dec byte ptr -0eH[bp] + jne L$12 +L$15: + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxcc.asm b/16/xw__/mxcc.asm new file mode 100755 index 00000000..f59177f8 --- /dev/null +++ b/16/xw__/mxcc.asm @@ -0,0 +1,629 @@ +.387 + PUBLIC XSUBCLIPLINE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + or al,byte ptr [bx+si] +L$2: + DW offset L$3 + or al,byte ptr [bx+si] + DW offset L$4 + or word ptr [bx+si],ax + DW offset L$5 + ???? + inc word ptr [bx+si] + add byte ptr [bp+si],cl + add byte ptr 0a00H[bx+si],al + add byte ptr 900H[bp],dl + add byte ptr -100H[si],ch + inc word ptr [bx+si] + add byte ptr ds:[0c000H],al + add byte ptr ds:[0ce00H],al + add byte ptr [di],al + add ah,bl + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + add bh,bh + inc word ptr [bx+si] + DB 0 +L$3: + DW offset MX_TEXT+0ecH + DW offset MX_TEXT+0eeH + DW offset MX_TEXT+0f1H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+0f4H + DW offset MX_TEXT+0f7H + DW offset MX_TEXT+104H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+111H + DW offset MX_TEXT+114H + DW offset MX_TEXT+121H +L$4: + DW offset MX_TEXT+132H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+135H + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+13bH + DW offset MX_TEXT+0eaH + DW offset MX_TEXT+148H + DW offset L$7 + DW offset L$10 + DW offset L$7 + DW offset L$11 +L$5: + DW offset L$14 + DW offset L$15 + DW offset L$7 + DW offset L$7 + DW offset L$16 + DW offset L$17 + DW offset L$7 + DW offset L$7 + DW offset L$18 + DW offset L$19 + DW offset L$22 + DW offset L$23 + DW offset L$24 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$25 + DW offset L$26 + DW offset L$27 + DW offset L$30 + DW offset L$7 + DW offset L$31 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$32 + DW offset L$7 + DW offset L$33 + DW offset L$36 + DW offset L$37 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$7 + DW offset L$38 + DW offset L$39 + DW offset L$43 + DW offset L$44 + DW offset L$45 + DW offset L$7 + DW offset L$46 + DW offset L$47 + DW offset L$48 + DW offset L$51 + DW offset L$7 + DW offset L$52 + DW offset L$7 + DW offset L$53 + DW offset L$7 + DW offset L$54 + DW offset L$58 + DW offset L$59 + DW offset L$7 + DW offset L$7 + DW offset L$60 + DW offset L$61 +L$6: + clc + ret +L$7: + stc + ret + clc + ret + jmp near ptr L$67 + jmp near ptr L$68 + jmp near ptr L$70 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$6 + jmp near ptr L$70 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jge L$6 + jmp near ptr L$70 + jmp near ptr L$69 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jle L$6 + jmp near ptr L$69 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jle L$6 + jmp near ptr L$69 +L$8: + stc + ret +L$9: + clc + ret + jmp near ptr L$63 + call near ptr L$63 + jmp near ptr L$68 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$8 + jmp near ptr L$70 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$8 + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX2 + jle L$9 + jmp near ptr L$68 +L$10: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$8 + jmp near ptr L$69 +L$11: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$8 + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX2 + jle L$9 + jmp near ptr L$68 +L$12: + clc + ret +L$13: + stc + ret +L$14: + jmp near ptr L$64 +L$15: + call near ptr L$64 + jmp near ptr L$67 +L$16: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$13 + jmp near ptr L$70 +L$17: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$13 + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX1 + jge L$12 + jmp near ptr L$67 +L$18: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$13 + jmp near ptr L$69 +L$19: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$13 + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX1 + jge L$12 + jmp near ptr L$67 +L$20: + clc + ret +L$21: + stc + ret +L$22: + jmp near ptr L$66 +L$23: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jl L$21 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$20 + jmp near ptr L$70 +L$24: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jg L$21 + jmp near ptr L$68 +L$25: + call near ptr L$66 + jmp near ptr L$69 +L$26: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jl L$21 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jle L$20 + jmp near ptr L$69 +L$27: + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jg L$21 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jle L$20 + jmp near ptr L$69 +L$28: + clc + ret +L$29: + stc + ret +L$30: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$28 + jmp near ptr L$66 +L$31: + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jl L$29 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jge L$28 + jmp near ptr L$63 +L$32: + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX1 + jl L$29 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX1 + jge L$28 + jmp near ptr L$63 +L$33: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$29 + call near ptr L$68 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$29 + cmp si,word ptr cs:MX_CLIPY2 + jle L$28 + jmp near ptr L$69 +L$34: + clc + ret +L$35: + stc + ret +L$36: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$37: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jl L$35 + call near ptr L$66 + cmp di,word ptr cs:MX_CLIPX2 + jle L$34 + jmp near ptr L$64 +L$38: + call near ptr L$69 + cmp cx,word ptr cs:MX_CLIPX2 + jg L$35 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$39: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jl L$35 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$35 + cmp si,word ptr cs:MX_CLIPY2 + jle L$40 + call near ptr L$69 +L$40: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$34 + jmp near ptr L$66 +L$41: + clc + ret +L$42: + stc + ret +L$43: + jmp near ptr L$65 +L$44: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jl L$42 + jmp near ptr L$67 +L$45: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jg L$42 + jmp near ptr L$68 +L$46: + call near ptr L$65 + jmp near ptr L$70 +L$47: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jl L$42 + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY1 + jge L$42 + jmp near ptr L$70 +L$48: + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jg L$42 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY1 + jge L$41 + jmp near ptr L$70 +L$49: + clc + ret +L$50: + stc + ret +L$51: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$49 + jmp near ptr L$65 +L$52: + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jg L$50 + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX1 + jge L$49 + jmp near ptr L$63 +L$53: + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX1 + jl L$50 + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$49 + jmp near ptr L$65 +L$54: + call near ptr L$63 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$50 + call near ptr L$68 + cmp si,word ptr cs:MX_CLIPY2 + jg L$50 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$55 + call near ptr L$65 +L$55: + cmp si,word ptr cs:MX_CLIPY1 + jge L$49 + jmp near ptr L$70 +L$56: + clc + ret +L$57: + stc + ret +L$58: + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp near ptr L$65 +L$59: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jg L$57 + call near ptr L$65 + cmp di,word ptr cs:MX_CLIPX2 + jle L$56 + jmp L$64 +L$60: + call near ptr L$70 + cmp cx,word ptr cs:MX_CLIPX2 + jg L$57 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp L$65 +L$61: + call near ptr L$67 + cmp si,word ptr cs:MX_CLIPY2 + jg L$57 + call near ptr L$64 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$57 + cmp si,word ptr cs:MX_CLIPY1 + jge L$62 + call near ptr L$70 +L$62: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$56 + jmp L$65 +L$63: + mov ax,si + sub ax,bx + mov dx,word ptr cs:MX_CLIPX1 + sub dx,di + imul dx + mov bp,cx + sub bp,di + idiv bp + add bx,ax + mov di,word ptr cs:MX_CLIPX1 + clc + ret +L$64: + mov ax,si + sub ax,bx + mov dx,word ptr cs:MX_CLIPX2 + sub dx,di + imul dx + mov bp,cx + sub bp,di + idiv bp + add bx,ax + mov di,word ptr cs:MX_CLIPX2 + clc + ret +L$65: + mov ax,cx + sub ax,di + mov dx,word ptr cs:MX_CLIPY2 + sub dx,bx + imul dx + mov bp,si + sub bp,bx + idiv bp + add di,ax + mov bx,word ptr cs:MX_CLIPY2 + clc + ret +L$66: + mov ax,cx + sub ax,di + mov dx,word ptr cs:MX_CLIPY1 + sub dx,bx + imul dx + mov bp,si + sub bp,bx + idiv bp + add di,ax + mov bx,word ptr cs:MX_CLIPY1 + clc + ret +L$67: + mov ax,bx + sub ax,si + mov dx,word ptr cs:MX_CLIPX1 + sub dx,cx + imul dx + mov bp,di + sub bp,cx + idiv bp + add si,ax + mov cx,word ptr cs:MX_CLIPX1 + clc + ret +L$68: + mov ax,bx + sub ax,si + mov dx,word ptr cs:MX_CLIPX2 + sub dx,cx + imul dx + mov bp,di + sub bp,cx + idiv bp + add si,ax + mov cx,word ptr cs:MX_CLIPX2 + clc + ret +L$69: + mov ax,di + sub ax,cx + mov dx,word ptr cs:MX_CLIPY2 + sub dx,si + imul dx + mov bp,bx + sub bp,si + idiv bp + add cx,ax + mov si,word ptr cs:MX_CLIPY2 + clc + ret +L$70: + mov ax,di + sub ax,cx + mov dx,word ptr cs:MX_CLIPY1 + sub dx,si + imul dx + mov bp,bx + sub bp,si + idiv bp + add cx,ax + mov si,word ptr cs:MX_CLIPY1 + clc + ret +XSUBCLIPLINE: + push bp + xor si,si + cmp dx,word ptr cs:MX_CLIPY2 + jle L$71 + or si,8 + jmp L$72 +L$71: + cmp dx,word ptr cs:MX_CLIPY1 + jge L$72 + or si,4 +L$72: + cmp cx,word ptr cs:MX_CLIPX2 + jle L$73 + or si,2 + jmp L$74 +L$73: + cmp cx,word ptr cs:MX_CLIPX1 + jge L$74 + or si,1 +L$74: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$75 + or si,80H + jmp L$76 +L$75: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$76 + or si,40H +L$76: + cmp ax,word ptr cs:MX_CLIPX2 + jle L$77 + or si,20H + jmp L$78 +L$77: + cmp ax,word ptr cs:MX_CLIPX1 + jge L$78 + or si,10H +L$78: + mov di,si + and di,0fH + and si,0f0H + shr si,1 + shr si,1 + cmp di,word ptr cs:L$1[si] + jg L$79 + mov si,word ptr cs:L$2[si] + shl di,1 + add si,di + mov di,ax + mov si,word ptr cs:[si] + xchg si,dx + call dx + mov ax,di + mov dx,si + pop bp + ret +L$79: + pop bp + stc + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxcg.asm b/16/xw__/mxcg.asm new file mode 100755 index 00000000..72cd3abf --- /dev/null +++ b/16/xw__/mxcg.asm @@ -0,0 +1,43 @@ +.387 + PUBLIC MXCOLORTOGRAY +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXCOLORTOGRAY: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov cx,word ptr 6[bp] + jcxz L$2 + lds si,dword ptr 0cH[bp] + les di,dword ptr 8[bp] + cld + mov bx,4d97H +L$1: + lodsb + mul bh + mov dx,ax + lodsb + mul bl + add dx,ax + lodsb + mov ah,1cH + mul ah + add ax,dx + mov al,ah + stosw + stosb + loop L$1 +L$2: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0aH +MX_TEXT ENDS + END diff --git a/16/xw__/mxcl.asm b/16/xw__/mxcl.asm new file mode 100755 index 00000000..1f5af641 --- /dev/null +++ b/16/xw__/mxcl.asm @@ -0,0 +1,111 @@ +.387 + PUBLIC MXCIRCLE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXCIRCLE: + push bp + mov bp,sp + sub sp,2 + push ds + push si + push di + xor si,si + mov di,word ptr 8[bp] + mov ax,3 + sub ax,di + sub ax,di + mov word ptr -2[bp],ax + mov ds,word ptr cs:MX_VIDEOSEGMENT +L$1: + cmp si,di + jg L$3 + mov ax,si + mov bx,di + call near ptr L$4 + mov ax,si + neg ax + mov bx,di + call near ptr L$4 + mov ax,si + mov bx,di + neg bx + call near ptr L$4 + mov ax,si + neg ax + mov bx,di + neg bx + call near ptr L$4 + mov ax,di + mov bx,si + call near ptr L$4 + mov ax,di + neg ax + mov bx,si + call near ptr L$4 + mov ax,di + mov bx,si + neg bx + call near ptr L$4 + mov ax,di + neg ax + mov bx,si + neg bx + call near ptr L$4 + mov ax,word ptr -2[bp] + test ax,ax + jl L$2 + mov ax,di + shl ax,1 + shl ax,1 + sub ax,4 + sub word ptr -2[bp],ax + dec di +L$2: + mov ax,si + shl ax,1 + shl ax,1 + add ax,6 + add word ptr -2[bp],ax + inc si + jmp L$1 +L$3: + xor ax,ax + pop di + pop si + pop ds + mov sp,bp + pop bp + retf 8 +L$4: + add bx,word ptr 0cH[bp] + add ax,word ptr 0aH[bp] + cmp bx,word ptr cs:MX_CLIPX1 + jl L$5 + cmp bx,word ptr cs:MX_CLIPX2 + jg L$5 + cmp ax,word ptr cs:MX_CLIPY1 + jl L$5 + cmp ax,word ptr cs:MX_CLIPY2 + jg L$5 + mul word ptr cs:MX_BYTESPERLINE + mov cx,bx + shr bx,1 + shr bx,1 + add bx,ax + and cl,3 + mov ax,102H + shl ah,cl + mov dx,3c4H + out dx,ax + mov al,byte ptr 6[bp] + mov byte ptr [bx],al +L$5: + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxcr.asm b/16/xw__/mxcr.asm new file mode 100755 index 00000000..254269f4 --- /dev/null +++ b/16/xw__/mxcr.asm @@ -0,0 +1,244 @@ +.387 + PUBLIC MX_CLIPX1 + PUBLIC MX_CLIPY1 + PUBLIC MX_CLIPX2 + PUBLIC MX_CLIPY2 + PUBLIC MXSETCLIP + PUBLIC MXGETCLIP + PUBLIC MXSETSYSCLIPREGION + PUBLIC MXSETCLIPREGION + PUBLIC MXGETCLIPREGION + PUBLIC SUBCLIPIMAGE + PUBLIC SUBCLIPBOX + EXTRN MX_CODESEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_CLIPX1: + add byte ptr [bx+si],al +MX_CLIPY1: + add byte ptr [bx+si],al +MX_CLIPX2: + add byte ptr [bx+si],al +MX_CLIPY2: + add byte ptr [bx+si],al +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +L$3: + add byte ptr [bx+si],al +L$4: + add byte ptr [bx+si],al +L$5: + add byte ptr [bx+si],al +L$6: + add byte ptr [bx+si],al +L$7: + add byte ptr [bx+si],al +L$8: + add byte ptr [bx+si],al +L$9: + DB 0 +MXSETCLIP: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr L$5 + mov bx,word ptr L$6 + mov cx,word ptr L$7 + mov dx,word ptr L$8 + cmp byte ptr 6[bp],1 + je L$10 + mov ax,word ptr L$1 + mov bx,word ptr L$2 + mov cx,word ptr L$3 + mov dx,word ptr L$4 +L$10: + mov word ptr MX_CLIPX1,ax + mov word ptr MX_CLIPY1,bx + mov word ptr MX_CLIPX2,cx + mov word ptr MX_CLIPY2,dx + mov al,byte ptr 6[bp] + xchg byte ptr L$9,al + xor ah,ah + pop ds + mov sp,bp + pop bp + retf 2 +MXGETCLIP: + mov al,byte ptr cs:L$9 + xor ah,ah + retf +MXSETSYSCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + xor ax,ax + mov word ptr L$1,ax + mov word ptr L$2,ax + mov ax,word ptr 8[bp] + dec ax + mov word ptr L$3,ax + mov ax,word ptr 6[bp] + dec ax + mov word ptr L$4,ax + mov ax,0 + push ax + push cs + call near ptr MXSETCLIP + pop ds + mov sp,bp + pop bp + retf 4 +MXSETCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 0cH[bp] + mov word ptr L$5,ax + mov ax,word ptr 0aH[bp] + mov word ptr L$6,ax + mov ax,word ptr 8[bp] + add ax,word ptr 0cH[bp] + dec ax + mov word ptr L$7,ax + mov ax,word ptr 6[bp] + add ax,word ptr 0aH[bp] + dec ax + mov word ptr L$8,ax + mov al,byte ptr L$9 + cmp al,1 + jne L$11 + push ax + push cs + call near ptr MXSETCLIP +L$11: + xor ax,ax + pop ds + mov sp,bp + pop bp + retf 8 +MXGETCLIPREGION: + push bp + mov bp,sp + sub sp,0 + push es + push di + mov ax,word ptr cs:L$5 + les di,dword ptr 12H[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$6 + les di,dword ptr 0eH[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$7 + sub ax,word ptr cs:L$5 + inc ax + les di,dword ptr 0aH[bp] + mov word ptr es:[di],ax + mov ax,word ptr cs:L$8 + sub ax,word ptr cs:L$6 + inc ax + les di,dword ptr 6[bp] + mov word ptr es:[di],ax + mov al,byte ptr cs:L$9 + xor ah,ah + pop di + pop es + mov sp,bp + pop bp + retf 10H +SUBCLIPIMAGE: + xor si,si + mov di,word ptr cs:MX_CLIPY1 + cmp ax,di + jge L$12 + sub di,ax + sub dx,di + jle L$16 + mov ax,di + mov di,dx + mul cx + mov si,ax + mov dx,di + mov ax,word ptr cs:MX_CLIPY1 +L$12: + mov di,word ptr cs:MX_CLIPY2 + cmp ax,di + jg L$16 + inc di + sub di,dx + sub di,ax + jge L$13 + add dx,di +L$13: + mov di,word ptr cs:MX_CLIPX1 + cmp bx,di + jge L$14 + sub di,bx + sub cx,di + jle L$16 + add si,di + mov bx,word ptr cs:MX_CLIPX1 +L$14: + mov di,word ptr cs:MX_CLIPX2 + cmp bx,di + jg L$16 + inc di + sub di,bx + sub di,cx + jge L$15 + add cx,di +L$15: + clc + ret +L$16: + stc + ret +SUBCLIPBOX: + mov di,word ptr cs:MX_CLIPY1 + cmp ax,di + jge L$17 + sub di,ax + sub dx,di + jle L$21 + mov ax,word ptr cs:MX_CLIPY1 +L$17: + mov di,word ptr cs:MX_CLIPY2 + cmp ax,di + jg L$21 + inc di + sub di,dx + sub di,ax + jge L$18 + add dx,di +L$18: + mov di,word ptr cs:MX_CLIPX1 + cmp bx,di + jge L$19 + sub di,bx + sub cx,di + jle L$21 + mov bx,word ptr cs:MX_CLIPX1 +L$19: + mov di,word ptr cs:MX_CLIPX2 + cmp bx,di + jg L$21 + inc di + sub di,bx + sub di,cx + jge L$20 + add cx,di +L$20: + clc + ret +L$21: + stc + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxel.asm b/16/xw__/mxel.asm new file mode 100755 index 00000000..e69de29b diff --git a/16/xw__/mxfb.asm b/16/xw__/mxfb.asm new file mode 100755 index 00000000..d0993a13 --- /dev/null +++ b/16/xw__/mxfb.asm @@ -0,0 +1,134 @@ +.387 + PUBLIC MXFILLBOX + EXTRN SUBCLIPBOX:BYTE + EXTRN SUBHORIZONTALLINEINFO:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov ah,al + shr cx,1 + rep stosw + rcl cx,1 + rep stosb + ret +L$2: + mov byte ptr [bx],al + add bx,dx + loop L$2 + ret +L$3: + mov si,di +L$4: + mov ah,byte ptr [si] + mov byte ptr [si],al + inc si + loop L$4 + ret +L$5: + mov ah,byte ptr [bx] + mov byte ptr [bx],al + add bx,dx + loop L$5 + ret +MXFILLBOX: + push bp + mov bp,sp + sub sp,8 + push ds + push si + push es + push di + mov bx,word ptr 10H[bp] + mov ax,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + mov dx,word ptr 0aH[bp] + call near ptr MX_TEXT:SUBCLIPBOX + jae L$6 + jmp near ptr L$12 +L$6: + mov word ptr 0aH[bp],dx + call near ptr MX_TEXT:SUBHORIZONTALLINEINFO + mov word ptr 0cH[bp],cx + mov byte ptr -2[bp],al + mov byte ptr -4[bp],ah + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov es,ax + mov ds,ax + cld + mov word ptr -6[bp],offset L$2 + mov word ptr -8[bp],offset L$1 + mov ax,word ptr 6[bp] + cmp al,3 + ja L$7 + cmp al,0 + je L$7 + shl al,1 + shl al,1 + shl al,1 + mov ah,al + mov al,3 + mov dx,3ceH + out dx,ax + mov word ptr -6[bp],offset L$5 + mov word ptr -8[bp],offset L$3 +L$7: + mov ah,byte ptr -2[bp] + or ah,ah + je L$8 + mov dx,3c4H + mov al,2 + out dx,ax + mov dx,word ptr cs:MX_BYTESPERLINE + mov cx,word ptr 0aH[bp] + mov bx,di + mov al,byte ptr 8[bp] + call word ptr -6[bp] + inc di +L$8: + mov cx,word ptr 0cH[bp] + jcxz L$10 + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov al,byte ptr 8[bp] + mov bx,di + mov dx,word ptr 0aH[bp] + push di +L$9: + mov di,bx + call word ptr -8[bp] + mov cx,word ptr 0cH[bp] + add bx,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$9 + pop di + add di,word ptr 0cH[bp] +L$10: + mov ah,byte ptr -4[bp] + or ah,ah + je L$11 + mov dx,3c4H + mov al,2 + out dx,ax + mov dx,word ptr cs:MX_BYTESPERLINE + mov cx,word ptr 0aH[bp] + mov bx,di + mov al,byte ptr 8[bp] + call word ptr -6[bp] +L$11: + mov dx,3ceH + mov ax,3 + out dx,ax +L$12: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw__/mxfp.asm b/16/xw__/mxfp.asm new file mode 100755 index 00000000..45900b0b --- /dev/null +++ b/16/xw__/mxfp.asm @@ -0,0 +1,220 @@ +.387 + PUBLIC MXFADEPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP + inc bx + outsw + jo L$5 + jb L$4 + push 2074H + sub byte ptr 29H[bp+di],ah + and byte ptr [bx+di],dh + cmp word ptr [bx+di],di + xor ch,byte ptr [di] + xor word ptr [bx+di],di + cmp word ptr [si],si + and byte ptr 52H[bx+di],al + push sp + dec cx + push bx + and byte ptr 2eH[bp+di],dh + jb L$1 + insb + and byte ptr cs:6cH[bx+di],al + insb + and byte ptr 69H[bp+si],dh + push 7374H + and byte ptr 65H[bp+si],dh + jae L$7 + jb L$9 + DB 65H, 64H, 2eH +MXFADEPALETTE: + push bp + mov bp,sp + sub sp,60aH + push si + push di + push ds + push es + mov word ptr -608H[bp],1 + mov ax,word ptr 10H[bp] + and ax,0ff00H +L$1: + je L$2 + mov cl,8 + shr ax,cl + mov word ptr -608H[bp],ax +L$2: + mov ax,word ptr 10H[bp] + and ax,0feH + mov cl,1 + shr ax,cl + or ax,ax + jne L$3 + mov ax,30H +L$3: + mov word ptr -60aH[bp],ax +L$4: + inc ax + mov byte ptr -606H[bp],al + mov byte ptr -604H[bp],1 + DB 0c6H, 86H, 0feH, 0f9H +L$5: + add byte ptr 0e46H[bp+di],cl + cmp ax,100H + jb L$6 + jmp near ptr L$12 +L$6: + add ax,word ptr 0cH[bp] + cmp ax,100H + jbe L$8 + mov ax,100H + sub ax,word ptr 0eH[bp] + DB 89H, 46H +L$7: + or al,0bH + ???? + jne L$8 + jmp near ptr L$12 +L$8: + mov cx,word ptr 0cH[bp] + mov ax,cx + shl ax,1 + add cx,ax + mov ax,ss +L$9: + mov es,ax + lea di,-300H[bp] + mov ax,word ptr 0eH[bp] + mov si,ax + shl ax,1 + add ax,si + lds si,dword ptr 12H[bp] + add si,ax + cld + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + test word ptr 10H[bp],1 + je L$10 + mov ax,word ptr -60aH[bp] + mov byte ptr -602H[bp],al + mov byte ptr -604H[bp],0ffH + mov ax,ss + mov ds,ax + mov es,ax + lea di,-300H[bp] + mov ax,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + call near ptr L$19 +L$10: + mov bh,byte ptr 0aH[bp] + and bh,3fH + mov bl,byte ptr 8[bp] + and bl,3fH + mov dh,byte ptr 6[bp] + and dh,3fH + mov dl,byte ptr -602H[bp] + mov ax,ss + mov ds,ax + mov es,ax +L$11: + mov ax,word ptr 0cH[bp] + mov cx,word ptr -60aH[bp] + lea si,-300H[bp] + lea di,-600H[bp] + call near ptr L$13 + push bx + push dx + lea si,-600H[bp] + mov ax,word ptr 0eH[bp] + mov bx,word ptr 0cH[bp] + mov cx,word ptr -608H[bp] + call near ptr L$15 + pop dx + pop bx + add dl,byte ptr -604H[bp] + dec byte ptr -606H[bp] + jne L$11 +L$12: + pop es + pop ds + pop di + pop si + mov sp,bp + pop bp + retf 10H +L$13: + cld + push bp + mov bp,ax +L$14: + lodsb + sub al,bh + imul dl + idiv cl + add al,bh + stosb + lodsb + sub al,bl + imul dl + idiv cl + add al,bl + stosb + lodsb + sub al,dh + imul dl + idiv cl + add al,dh + stosb + dec bp + jne L$14 + pop bp + ret +L$15: + mov ah,al + mov dx,3daH +L$16: + in al,dx + test al,8 + jne L$16 +L$17: + in al,dx + test al,8 + je L$17 + loop L$16 + mov cx,bx + mov dx,3c8H + mov al,ah + out dx,al + inc dx + cld + cli +L$18: + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + loop L$18 + sti + ret +L$19: + mov dx,3c7H + out dx,al + inc dx + inc dx + cld +L$20: + in al,dx + stosb + in al,dx + stosb + in al,dx + stosb + loop L$20 + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxgc.asm b/16/xw__/mxgc.asm new file mode 100755 index 00000000..5b128d22 --- /dev/null +++ b/16/xw__/mxgc.asm @@ -0,0 +1,31 @@ +.387 + PUBLIC MXGETCOLOR +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr 12H[bp] + mov dx,3c7H + out dx,al + inc dx + inc dx + lds si,dword ptr 0eH[bp] + in al,dx + mov byte ptr [si],al + lds si,dword ptr 0aH[bp] + in al,dx + mov byte ptr [si],al + lds si,dword ptr 6[bp] + in al,dx + mov byte ptr [si],al + pop si + pop ds + mov sp,bp + pop bp + retf 0eH +MX_TEXT ENDS + END diff --git a/16/xw__/mxgi.asm b/16/xw__/mxgi.asm new file mode 100755 index 00000000..36fe7087 --- /dev/null +++ b/16/xw__/mxgi.asm @@ -0,0 +1,99 @@ +.387 + PUBLIC MXGETIMAGE + EXTRN SUBCLIPIMAGE:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETIMAGE: + push bp + mov bp,sp + sub sp,10H + push ds + push si + push es + push di + mov bx,word ptr 0cH[bp] + mov ax,word ptr 0aH[bp] + mov cx,word ptr 8[bp] + mov dx,word ptr 6[bp] + call near ptr MX_TEXT:SUBCLIPIMAGE + jae L$1 + jmp near ptr L$7 +L$1: + mov word ptr 6[bp],dx + add word ptr 0eH[bp],si + mul word ptr cs:MX_BYTESPERLINE + mov si,bx + shr si,1 + shr si,1 + add si,ax + mov word ptr -0aH[bp],si + mov ds,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -0eH[bp],bl + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov di,6 +L$2: + mov word ptr -8[bp+di],bx + shr al,1 + adc bx,0 + dec di + dec di + jge L$2 + cld + mov byte ptr -10H[bp],4 + lea bx,-8[bp] + mov es,word ptr 10H[bp] + mov ah,byte ptr -0eH[bp] +L$3: + cmp word ptr ss:[bx],0 + je L$7 + mov di,word ptr 0eH[bp] + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 6[bp] + mov si,word ptr -0aH[bp] +L$4: + push si + push di + mov cx,word ptr ss:[bx] +L$5: + movsb + add di,3 + dec cx + jne L$5 + pop di + pop si + add di,word ptr 8[bp] + add si,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$4 + inc bx + inc bx + inc ah + test ah,4 + je L$6 + inc word ptr -0aH[bp] + and ah,3 +L$6: + inc word ptr 0eH[bp] + dec byte ptr -10H[bp] + jne L$3 +L$7: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw__/mxgm.asm b/16/xw__/mxgm.asm new file mode 100755 index 00000000..0c97985d --- /dev/null +++ b/16/xw__/mxgm.asm @@ -0,0 +1,69 @@ +.387 + PUBLIC MXGAMMACORRECT +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bp+si],cl + push cs + adc word ptr [bp+di],dx + adc ax,1817H + sbb bl,byte ptr [bp+di] + sbb al,1dH + pop ds + and byte ptr [bx+di],ah + and ah,byte ptr [bp+di] + and al,25H + and ax,2726H + sub byte ptr [bx+di],ch + sub word ptr [bp+si],bp + sub bp,word ptr [si] + sub al,2dH + das + xor byte ptr [bx+si],dh + xor word ptr [bx+di],si + xor dh,byte ptr [bp+di] + xor si,word ptr [si] + xor al,35H + xor ax,3636H + aaa + aaa + cmp byte ptr [bx+si],bh + cmp word ptr [bx+di],di + cmp bh,byte ptr [bp+si] + cmp di,word ptr [bp+di] + cmp al,3cH + cmp ax,3e3dH + aas + aas +MXGAMMACORRECT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov cx,word ptr 6[bp] + jcxz L$3 + lds si,dword ptr 0cH[bp] + les di,dword ptr 8[bp] + mov bx,offset L$1 + cld + mov ax,cx + add cx,cx + add cx,ax +L$2: + lodsb + xlat word ptr cs:[bx] + stosb + loop L$2 +L$3: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0aH +MX_TEXT ENDS + END diff --git a/16/xw__/mxgp.asm b/16/xw__/mxgp.asm new file mode 100755 index 00000000..19a10ccc --- /dev/null +++ b/16/xw__/mxgp.asm @@ -0,0 +1,33 @@ +.387 + PUBLIC MXGETPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETPALETTE: + push bp + mov bp,sp + sub sp,0 + push es + push di + les di,dword ptr 0aH[bp] + mov cx,word ptr 6[bp] + mov ax,word ptr 8[bp] + mov dx,3c7H + out dx,al + inc dx + inc dx + cld +L$1: + in al,dx + stosb + in al,dx + stosb + in al,dx + stosb + loop L$1 + pop di + pop es + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxgv.asm b/16/xw__/mxgv.asm new file mode 100755 index 00000000..bbe19c95 --- /dev/null +++ b/16/xw__/mxgv.asm @@ -0,0 +1,9 @@ +.387 + PUBLIC MXGETVERSION +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETVERSION: + mov ax,128H + retf +MX_TEXT ENDS + END diff --git a/16/xw__/mxhl.asm b/16/xw__/mxhl.asm new file mode 100755 index 00000000..159e5c99 --- /dev/null +++ b/16/xw__/mxhl.asm @@ -0,0 +1,45 @@ +.387 + PUBLIC SUBHORIZONTALLINEINFO + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bx+si],al + add ax,word ptr [bx+si] + add al,byte ptr [bx+si] + add word ptr [bx+si],ax +L$2: + add byte ptr ds:[80cH],cl +L$3: + add byte ptr [bx+di],al + add ax,word ptr [bx] +L$4: + DB 2, 6 +SUBHORIZONTALLINEINFO: + DD ds:[0f72eH] + add byte ptr -2e05H[bp+di],cl + out dx,ax + shr di,1 + add di,ax + and bx,3 + mov al,byte ptr cs:L$2[bx] + shl bx,1 + sub cx,word ptr cs:L$1[bx] + jge L$5 + mov bx,cx + inc bx + inc bx + and al,byte ptr cs:L$4[bx] + xor ah,ah + xor cx,cx + jmp L$6 +L$5: + mov bx,cx + and bx,3 + mov ah,byte ptr cs:L$3[bx] + shr cx,1 + shr cx,1 +L$6: + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxit.asm b/16/xw__/mxit.asm new file mode 100755 index 00000000..4f68fddd --- /dev/null +++ b/16/xw__/mxit.asm @@ -0,0 +1,92 @@ +.387 + PUBLIC MX_VIDEOSEGMENT + PUBLIC MX_CODESEGMENT + PUBLIC MXINIT + PUBLIC MXTERM +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP + dec bp + dec di + inc sp + inc bp + pop ax + and byte ptr 69H[si],ch + bound si,word ptr 61H[bp+si] + jb L$3 + and byte ptr [di],ch + and byte ptr 6fH[bp+di],al + jo L$5 + jb L$2 + push 2074H + sub byte ptr 29H[bp+di],ah + and byte ptr [bx+di],dh + cmp word ptr [bx+di],di + xor ch,byte ptr [di] + xor word ptr [bx+di],di + cmp word ptr [si],si + and byte ptr 6cH[bx+di],al + ; The label referred to here is an undefined location + jae 0a0H + popa + outsb + ; The label referred to here is an undefined location + jb 0a1H + and byte ptr 63H[bp+di],dl + outsw + ; The label referred to here is an undefined location + je 0acH + DB 69H +MX_VIDEOSEGMENT: + DB 0, 0a0H +MX_CODESEGMENT: + DW MX_TEXT +MXINIT: + push bp + mov bp,sp + sub sp,6 + push ds + push si + push es + push di + mov word ptr -2[bp],0ffffH + mov word ptr -4[bp],0a000H + mov word ptr -6[bp],cs + mov ax,1686H + int 2fH + or ax,ax + jne L$1 + mov ax,0aH + mov bx,cs + int 31H + jb L$4 + mov word ptr -6[bp],ax + mov ax,2 + mov bx,0a000H + int 31H + jb L$4 + mov word ptr -4[bp],ax +L$1: + mov ds,word ptr -6[bp] + mov word ptr MX_CODESEGMENT,ds + DB 8bH, 46H +L$2: + cld + mov word ptr MX_VIDEOSEGMENT,ax + DB 0c7H, 46H, 0feH +L$3: + add byte ptr [bx+si],al +L$4: + mov ax,word ptr -2[bp] + pop di + pop es +L$5: + pop si + pop ds + mov sp,bp + pop bp + retf +MXTERM: + xor ax,ax + retf +MX_TEXT ENDS + END diff --git a/16/xw__/mxll.asm b/16/xw__/mxll.asm new file mode 100755 index 00000000..94e5b2cd --- /dev/null +++ b/16/xw__/mxll.asm @@ -0,0 +1,51 @@ +.387 + PUBLIC MXLOADLATCHES + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXLOADLATCHES: + push ds + push si + mov dx,3ceH + mov ax,0ff08H + out dx,ax + mov ax,3 + out dx,ax + mov ax,5 + out dx,ax + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + mov si,0ffffH + mov bh,8 + mov cx,3 +L$1: + mov dx,3ceH + mov al,4 + mov ah,cl + out dx,ax + mov dx,3c4H + mov al,2 + mov ah,bh + out dx,ax + mov al,byte ptr [si] + push ax + mov byte ptr [si],bl + mov al,byte ptr [di] + shr bh,1 + loop L$1 + mov cx,3 + mov bh,8 + mov dx,3c4H +L$2: + mov al,2 + mov ah,bh + out dx,ax + pop ax + mov byte ptr [si],al + shr bh,1 + loop L$2 + pop si + pop ds + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxln.asm b/16/xw__/mxln.asm new file mode 100755 index 00000000..b488734b --- /dev/null +++ b/16/xw__/mxln.asm @@ -0,0 +1,333 @@ +.387 + PUBLIC MXLINE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$29 + DW offset L$32 + DW offset L$35 + DW offset L$38 +MXLINE: + push bp + mov bp,sp + sub sp,12H + push ds + push si + push di + mov ax,word ptr 10H[bp] + mov bx,word ptr 0eH[bp] + mov cx,word ptr 0cH[bp] + mov dx,word ptr 0aH[bp] + call near ptr L$8 + jae L$2 + jmp near ptr L$7 +L$2: + mov si,cx + xchg ax,si + sub ax,si + jge L$3 + xchg cx,si + xchg dx,bx + neg ax +L$3: + mov word ptr -2[bp],ax + mov cx,word ptr cs:MX_BYTESPERLINE + mov ax,dx + sub ax,bx + jge L$4 + neg cx + neg ax +L$4: + mov word ptr -4[bp],ax + mov word ptr -0cH[bp],cx + mov ax,bx + mul word ptr cs:MX_BYTESPERLINE + mov cx,si + shr si,1 + shr si,1 + add si,ax + and cl,3 + mov ax,1102H + shl ah,cl + mov byte ptr -12H[bp],ah + mov dx,3c4H + out dx,ax + mov ax,word ptr cs:MX_VIDEOSEGMENT + mov ds,ax + xor bx,bx + mov al,byte ptr 6[bp] + cmp al,0 + je L$5 + and al,3 + shl al,1 + shl al,1 + shl al,1 + mov ah,al + mov al,3 + mov dx,3ceH + out dx,ax + inc bx + inc bx +L$5: + mov ax,word ptr -2[bp] + mov cx,word ptr -4[bp] + cmp ax,cx + jae L$6 + inc bx +L$6: + shl bx,1 + call word ptr cs:L$1[bx] + cmp byte ptr 6[bp],0 + je L$7 + mov ax,3 + mov dx,3ceH + out dx,ax +L$7: + xor ax,ax + pop di + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +L$8: + mov di,ax + mov si,dx + xor al,al + cmp cx,word ptr cs:MX_CLIPX1 + jge L$9 + or al,1 +L$9: + cmp cx,word ptr cs:MX_CLIPX2 + jle L$10 + or al,2 +L$10: + cmp si,word ptr cs:MX_CLIPY1 + jge L$11 + or al,4 +L$11: + cmp si,word ptr cs:MX_CLIPY2 + jle L$12 + or al,8 +L$12: + mov byte ptr -10H[bp],al + xor al,al + cmp di,word ptr cs:MX_CLIPX1 + jge L$13 + or al,1 +L$13: + cmp di,word ptr cs:MX_CLIPX2 + jle L$14 + or al,2 +L$14: + cmp bx,word ptr cs:MX_CLIPY1 + jge L$15 + or al,4 +L$15: + cmp bx,word ptr cs:MX_CLIPY2 + jle L$16 + or al,8 +L$16: + mov byte ptr -0eH[bp],al + mov ah,byte ptr -10H[bp] + test ah,al + je L$17 + jmp near ptr L$28 +L$17: + or ah,al + jne L$18 + jmp near ptr L$27 +L$18: + mov ax,cx + sub ax,di + mov word ptr -0aH[bp],ax + mov ax,si + sub ax,bx + mov word ptr -0cH[bp],ax + mov al,byte ptr -0eH[bp] +L$19: + test al,al + jne L$20 + xchg di,cx + xchg si,bx + xchg byte ptr -10H[bp],al +L$20: + test al,1 + je L$21 + mov ax,word ptr cs:MX_CLIPX1 + sub ax,di + mov di,word ptr cs:MX_CLIPX1 + jmp L$22 +L$21: + test al,2 + je L$23 + mov ax,word ptr cs:MX_CLIPX2 + sub ax,di + mov di,word ptr cs:MX_CLIPX2 +L$22: + imul word ptr -0cH[bp] + idiv word ptr -0aH[bp] + add bx,ax + mov al,8 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$26 + mov al,4 + cmp bx,word ptr cs:MX_CLIPY1 + jl L$26 + xor al,al + jmp L$26 +L$23: + test al,4 + je L$24 + mov ax,word ptr cs:MX_CLIPY1 + sub ax,bx + mov bx,word ptr cs:MX_CLIPY1 + jmp L$25 +L$24: + mov ax,word ptr cs:MX_CLIPY2 + sub ax,bx + mov bx,word ptr cs:MX_CLIPY2 +L$25: + imul word ptr -0aH[bp] + idiv word ptr -0cH[bp] + add di,ax + mov al,1 + cmp di,word ptr cs:MX_CLIPX1 + jl L$26 + mov al,2 + cmp di,word ptr cs:MX_CLIPX2 + jg L$26 + xor al,al +L$26: + mov ah,byte ptr -10H[bp] + test ah,al + jne L$28 + or ah,al + je L$27 + jmp near ptr L$19 +L$27: + mov ax,di + mov dx,si + clc + ret +L$28: + stc + ret +L$29: + mov di,ax + neg di + shl cx,1 + mov word ptr -6[bp],cx + mov cx,ax + shl ax,1 + mov word ptr -8[bp],ax + mov al,2 + mov ah,byte ptr -12H[bp] + mov bl,byte ptr 8[bp] + mov dx,3c4H + inc cx +L$30: + mov byte ptr [si],bl + dec cx + je L$31 + rol ah,1 + adc si,0 + out dx,ax + add di,word ptr -6[bp] + jl L$30 + add si,word ptr -0cH[bp] + sub di,word ptr -8[bp] + jmp L$30 +L$31: + ret +L$32: + mov di,cx + neg di + shl ax,1 + mov word ptr -6[bp],ax + mov ax,cx + shl ax,1 + mov word ptr -8[bp],ax + mov bl,byte ptr 8[bp] + mov ah,byte ptr -12H[bp] + mov al,2 + mov dx,3c4H + inc cx +L$33: + mov byte ptr [si],bl + dec cx + je L$34 + add si,word ptr -0cH[bp] + add di,word ptr -6[bp] + jl L$33 + rol ah,1 + adc si,0 + out dx,ax + sub di,word ptr -8[bp] + jmp L$33 +L$34: + ret +L$35: + mov di,ax + neg di + shl cx,1 + mov word ptr -6[bp],cx + mov cx,ax + shl ax,1 + mov word ptr -8[bp],ax + mov al,2 + mov ah,byte ptr -12H[bp] + mov bl,byte ptr 8[bp] + mov dx,3c4H + inc cx +L$36: + mov bh,byte ptr [si] + mov byte ptr [si],bl + dec cx + je L$37 + rol ah,1 + adc si,0 + out dx,ax + add di,word ptr -6[bp] + jl L$36 + add si,word ptr -0cH[bp] + sub di,word ptr -8[bp] + jmp L$36 +L$37: + ret +L$38: + mov di,cx + neg di + shl ax,1 + mov word ptr -6[bp],ax + mov ax,cx + shl ax,1 + mov word ptr -8[bp],ax + mov bl,byte ptr 8[bp] + mov ah,byte ptr -12H[bp] + mov al,2 + mov dx,3c4H + inc cx +L$39: + mov bh,byte ptr [si] + mov byte ptr [si],bl + dec cx + je L$40 + add si,word ptr -0cH[bp] + add di,word ptr -6[bp] + jl L$39 + rol ah,1 + adc si,0 + out dx,ax + sub di,word ptr -8[bp] + jmp L$39 +L$40: + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxot.asm b/16/xw__/mxot.asm new file mode 100755 index 00000000..7bd60113 --- /dev/null +++ b/16/xw__/mxot.asm @@ -0,0 +1,1310 @@ +.387 + PUBLIC MXSETFONT + PUBLIC MXSETTEXTCOLOR + PUBLIC MXOUTCHAR + PUBLIC MXOUTTEXT + PUBLIC MXSETTEXTSTEP + PUBLIC MXGETTEXTSTEP + EXTRN MX_CODESEGMENT:BYTE + EXTRN MXPUTIMAGE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ; The label referred to here is an undefined location + jle 0ffffff8bH + movsw + and word ptr -7e67H[di],7e7eH + call bx + call bx + out 0ffH,ax + jle L$9 + ???? + ???? + ???? + jl L$7 + adc byte ptr [bx+si],al + adc byte ptr [bx+si],bh +L$2: + jl L$2 + jl L$8 + adc byte ptr [bx+si],al + adc byte ptr [bx+si],bh + adc byte ptr -2[si],dl + push sp + adc dh,bh + adc byte ptr [bx+si],bh +L$3: + jl L$3 +L$4: + ???? + jl L$5 + inc byte ptr [bx+si] + sbb byte ptr [si],bh + jle L$11 + cmp al,18H + add bh,bh + out 0c3H,ax + DB 81H, 81H, 0c3H, 0e7H +L$5: + inc word ptr [bx+si] + cmp al,66H + inc dx + inc dx + DB 66H, 3cH +L$6: + add bh,bh + ret + cwd + mov bp,99bdH +L$7: + ret + inc word ptr [bx] + add ax,word ptr [di] + ; The label referred to here is an undefined location + js 0ffffffe1H + DB 84H +L$8: + test byte ptr 7cH[bx+si],bh + add byte ptr 7c82H[bp+si],10H + cmp byte ptr [bx+si],dl + sbb al,10H + sbb al,10H + adc byte ptr [bx+si],dl + xor byte ptr [bx+si],dh + and bh,byte ptr ds:[2222H] + pushad + cwd + pop dx + cmp al,0e7H + out 3cH,ax + pop dx + cwd + add byte ptr [bx+si],dl + xor byte ptr -10H[bx+si],dh +L$9: + jo L$10 + adc byte ptr [bx+si],al + add al,0e0H + lock loopnz L$6 + adc byte ptr [bx+si],38H + push sp + adc byte ptr [bx+si],dl + push sp + cmp byte ptr [bx+si],dl + dec ax + dec ax + dec ax + dec ax + dec ax + add byte ptr [bx+si],cl + jle L$4 + xchg ax,dx + jb L$10 + adc dl,byte ptr [bp+si] + add byte ptr [si],bh + and bl,byte ptr [bx+si] + and al,24H + sbb byte ptr 3cH[si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + DB 0, 3eH + DD ds:[3eH] +L$10: + add byte ptr [bx+si],bh + push sp + DB 10H +L$11: + adc byte ptr [bx+si],dl + push sp + cmp dh,bh + add byte ptr [bx+si],dl + cmp byte ptr 10H[si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr 38H[si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],cl + add al,0feH + add al,8 + add byte ptr [bx+si],al + add byte ptr [bx+si],ah + inc ax + inc byte ptr 20H[bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr -380H[bx+si],0 + add byte ptr [bx+si],al + and al,42H + inc word ptr 24H[bp+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],bh +L$12: + jl L$12 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ???? + jl L$15 + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],dl + add byte ptr [bx+si],al + and al,24H + add byte ptr [bx+si],al + DB 0 +L$13: + add byte ptr [bx+si],al + and al,24H + jle 140H + jle 142H +L$14: + and al,0 + cmp byte ptr 50H[si],dl + cmp byte ptr [si],dl + push sp + cmp byte ptr [bx+si],dl + add byte ptr [bp+si],al + inc sp + or byte ptr [bx+si],dl + and byte ptr [bp+si],al + cmp byte ptr 38H[si],al + pusha + xchg ax,sp +L$15: + DB 88H +L$16: + je 138H + and byte ptr [bx+si],ah + inc ax + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + and byte ptr 40H[bx+si],al + inc ax + and byte ptr [bx+si],dl + add byte ptr 20H[bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],ah +L$17: + inc ax + add byte ptr [bx+si],al + and al,18H + jle L$18 + and al,0 + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + jl L$18 + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],dl + and byte ptr [bx+si],al + add byte ptr [bx+si],al + cld + DB 0 +L$18: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + add byte ptr [bx+si],al + add al,8 + adc byte ptr [bx+si],ah + inc ax +L$19: + add byte ptr [bx+si],7cH + ???? + DB 8aH, 92H +L$20: + mov byte ptr 0c6H,al + DD L$21 +L$21: + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],bh + add byte ptr L$13[bx+si],bh + add al,18H + pusha + cmp ah,0 + js L$14 + add al,38H + add al,84H + js L$22 +L$22: + sbb al,24H + inc sp + test dh,bh + add al,0eH + add ah,bh + cmp al,4 + add al,84H + js L$23 +L$23: + js L$16 + cmp al,84H + test byte ptr [bx+si],bh + cld + add al,4 + or byte ptr [bx+si],dl + and byte ptr [bx+si],ah + add byte ptr -7cH[bx+si],bh + test byte ptr -7cH[bx+si],bh + test byte ptr [bx+si],bh + js L$17 + test byte ptr 4[si],bh + test byte ptr [bx+si],bh + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + add byte ptr [bx+si],dl + adc byte ptr [bx+si],ah + or byte ptr [bx+si],dl + and byte ptr 20H[bx+si],al + adc byte ptr [bx+si],cl + add byte ptr [bx+si],al + add ah,bh + add byte ptr [bx+si],al + cld + add byte ptr [bx+si],al + inc ax + and byte ptr [bx+si],dl + or byte ptr [bx+si],dl + and byte ptr [bx+si],al + js L$19 + add al,8 + adc byte ptr [bx+si],al +L$24: + adc byte ptr [bx+si],al + jl L$20 + mov dx,0bea6H + cmp byte ptr [si],78H + test byte ptr -7b04H[si],al + test byte ptr -800H[si],al + test byte ptr -7b08H[si],al + test al,bh + add byte ptr -7cH[bx+si],bh + add byte ptr -7b80H[bx+si],78H + add al,dh + mov byte ptr -7b7cH[si],al + mov al,dh + add ah,bh + add byte ptr -7f10H[bx+si],80H + cld + add ah,bh + add byte ptr -7f10H[bx+si],80H + add byte ptr [bx+si],78H + test byte ptr -7b64H[bx+si],al + test byte ptr [bx+si],bh + test byte ptr -37cH[si],al + test byte ptr 84H[si],al + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + cmp byte ptr [bx+si],al + sbb al,8 + or byte ptr [bx+si],cl + mov byte ptr 70H[bx+si],cl + test byte ptr -1f70H[bx+si],cl + nop + mov byte ptr -8000H[si],al + add byte ptr -7f80H[bx+si],80H + cld + add dh,al + stosb + xchg ax,dx + add byte ptr -7d7eH[bp+si],0 + add dl,0a2H + xchg ax,dx + mov al,byte ptr 82H[bp] + js L$24 + test byte ptr -7b7cH[si],al + js L$25 +L$25: + clc + test byte ptr -7f08H[si],al + add byte ptr 7800H[bx+si],84H + test byte ptr -776cH[si],al + jbe L$26 +L$26: + clc + test byte ptr -6f08H[si],al + mov byte ptr 7800H[si],al + test byte ptr 478H[bx+si],al + test byte ptr [bx+si],bh + ???? + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr -7b7cH[si],al + test byte ptr 7884H[si],al + add byte ptr -7b7cH[si],al + test byte ptr 3048H[si],al + add byte ptr -7d7eH[bp+si],al + adc byte ptr -3956H[bp+si],0 + add byte ptr 28H[si],10H + sub byte ptr -7eH[si],al + add byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add dh,bh + add al,8 + adc byte ptr [bx+si],ah + inc ax + inc byte ptr [bx+si] + js L$32 + inc ax + inc ax + inc ax + inc ax + js L$27 +L$27: + add byte ptr 2040H[bx+si],al + adc byte ptr [bx+si],cl + add al,0 + js L$29 + or byte ptr [bx+si],cl + or byte ptr [bx+si],cl + js L$28 +L$28: + adc byte ptr [bx+si],ch +L$29: + inc sp + add byte ptr [bx+si],0 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + and byte ptr [bx+si],ah + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp byte ptr [si],al + cmp al,44H + jl L$30 +L$30: + add byte ptr 40H[bx+si],al + js L$33 + inc sp + js L$31 +L$31: + add byte ptr [bx+si],al +L$32: + cmp al,40H + inc ax + inc ax + cmp al,0 + add byte ptr [si],al + add al,3cH + inc sp + inc sp + cmp al,0 + add byte ptr [bx+si],al + cmp byte ptr 7cH[si],al + inc ax + cmp al,0 + add byte ptr [si],cl + adc byte ptr [si],bh + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,44H + inc sp + cmp al,4 + cmp byte ptr [bx+si],al + inc ax + inc ax + js L$35 + inc sp + inc sp + add byte ptr [bx+si],al + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + add al,0 + add al,4 + add al,44H + cmp byte ptr [bx+si],al +L$33: + inc ax + inc ax + push ax + pusha + push ax + dec ax + add byte ptr [bx+si],al + xor byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + add byte ptr [bx+si],al + add byte ptr 54H[bx+si],ch + push sp + inc sp + inc sp + add byte ptr [bx+si],al + add byte ptr 44H[bx+si],bh + inc sp + inc sp + inc sp + add byte ptr [bx+si],al + add byte ptr [bx+si],bh + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al +L$34: + js L$42 + inc sp + js L$41 + inc ax + DB 0 +L$35: + add byte ptr [si],bh + inc sp + inc sp + cmp al,4 + add al,0 + add byte ptr 60H[si],bl + inc ax + inc ax + inc ax + add byte ptr [bx+si],al + add byte ptr [bx+si],bh +L$36: + inc ax + jl L$38 + jl L$37 +L$37: + add byte ptr [bx+si],dl +L$38: + cmp byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + sub byte ptr [bx+si],dl + add byte ptr [bx+si],al + add byte ptr 44H[si],al +L$39: + push sp + push sp + insb + add byte ptr [bx+si],al + add byte ptr 28H[si],al +L$40: + adc byte ptr [bx+si],ch + inc sp +L$41: + DB 0 +L$42: + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp al,4 + jl L$43 +L$43: + add byte ptr 4[si],bh + cmp byte ptr 7cH[bx+si],al + add byte ptr [bx+si],al + or byte ptr [bx+si],dl + adc byte ptr [bx+si],dh + adc byte ptr [bx+si],dl + or byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + and byte ptr [bx+si],dl + adc byte ptr [bx+si],bl + adc byte ptr [bx+si],dl + and byte ptr -68H[si],ah + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],dl + sub byte ptr -7eH[si],al + cmp dh,0 + jl L$34 + add byte ptr 7c80H[bx+si],4 + jl L$44 +L$44: + sub byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + cmp al,0 + jl L$54 + jl L$53 + jl L$45 +L$45: + jle L$36 + cmp byte ptr [si],al + cmp al,44H + jl L$46 +L$46: + and al,0 +L$47: + cmp byte ptr [si],al + cmp al,44H + jl L$48 +L$48: + js L$49 +L$49: + cmp byte ptr [si],al + cmp al,44H + jl L$50 +L$50: + sbb byte ptr [bx+si],bl + cmp byte ptr [si],al + cmp al,44H + jl L$51 +L$51: + add byte ptr [bx+si],al + js L$39 + cmp byte ptr 8[bx+si],38H + jl L$40 + cmp byte ptr 7cH[si],al + inc ax + cmp al,0 + dec ax + add byte ptr [bx+si],bh + inc sp + jl L$55 + cmp al,0 + js L$52 +L$52: + cmp byte ptr 7cH[si],al + inc ax +L$53: + cmp al,0 +L$54: + add byte ptr [bx+si],ch + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + adc byte ptr [bx+si],ch + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + add byte ptr [bx+si],dh + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + dec ax + add byte ptr -7cH[bx+si],bh + cld + test byte ptr 3000H[si],al + xor byte ptr -7cH[bx+si],bh + cld + test byte ptr 3800H[si],al + add ah,bh + xor al,80H + cld + add byte ptr [bx+si],al + add byte ptr 8[bp],bh + jle L$59 +L$55: + jle L$56 +L$56: + jle L$47 + nop + cld + nop + nop + sahf + add byte ptr -7eH[si],bh + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + sub byte ptr [bx+si],al + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + jo L$57 +L$57: + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + cmp byte ptr [si],al + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + jo L$58 +L$58: + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + sub byte ptr [bx+si],al + inc sp + inc sp + inc sp + cmp al,4 + jl L$64 + add byte ptr -7cH[bx+si],bh + test byte ptr 78H[si],al + dec ax + add byte ptr -7b7cH[si],al + DB 84H +L$59: + js 4d8H + add byte ptr [bx+si],dl + cmp byte ptr 40H[bx+si],al + inc ax + cmp byte ptr [bx+si],dl + cmp byte ptr 40H[si],al + loopnz L$66 + inc ax + cmp ah,44H + jl L$60 + jl L$61 + jl L$62 + add al,dh + mov byte ptr -7d09H[bp+si],cl + add byte ptr 0c00H[bp+si],12H + DB 10H +L$60: + sbb byte ptr [bx+si],dh +L$61: + DB 10H, 90H +L$62: + pusha + cmp al,0 + cmp byte ptr [si],al + cmp al,44H + jl L$63 +L$63: + add byte ptr [bx+si],bl + add byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],al + DB 1cH +L$64: + add byte ptr [bx+si],bh + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + sbb al,0 + inc sp + inc sp + inc sp + inc sp + cmp byte ptr [bx+si],al + jl L$65 +L$65: + js L$67 + inc sp +L$66: + inc sp + inc sp + add byte ptr [si],bh + inc sp + push sp + dec sp + inc sp + add byte ptr [bx+si],bl + and al,24H + push ds + add byte ptr ds:[0],bh + sbb al,22H + and bl,byte ptr [si] + add byte ptr ds:[0],bh + adc byte ptr [bx+si],al + adc byte ptr [bx+si],ah + inc ax + inc dx + cmp al,0 + add byte ptr [bx+si],al + add ah,bh + add byte ptr [bx+si],0 + add byte ptr [bx+si],al + cld + add al,4 + add byte ptr [bx+si],al + inc ax + inc sp + dec ax + push di + and word ptr 4[bx],ax + pop es + inc ax + inc sp + dec ax + push dx + dec dx + pop ds + DB 2 +L$67: + adc byte ptr [bx+si],al + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl +L$68: + adc byte ptr [bx+si],al + add byte ptr [si],ah +L$69: + dec ax + nop + dec ax + and al,0 + add byte ptr [bx+si],al + dec ax + and al,12H + and al,48H + add byte ptr [bx+si],al + and cl,byte ptr -77deH[bx+si] + and cl,byte ptr -77deH[bx+si] + push bp + stosb + push bp + stosb + push bp + stosb + push bp + stosb + ???? + ja L$68 + out dx,al + ???? + ja L$69 + out dx,al + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + clc + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb al,bh + sbb al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[3636H],dh + div byte ptr ss:[3636H] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + ???? + add byte ptr ss:[bx+si],al + clc + sbb al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[0f636H],dh + push es + div byte ptr ds:[3636H] + add byte ptr ss:[bx+si],al + inc byte ptr ds:[36f6H] + test byte ptr ss:[0feH],0 + add byte ptr ds:[3636H],dh + inc byte ptr ss:[bx+si] + add byte ptr [bx+si],al + sbb byte ptr [bx+si],bl + clc + sbb al,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add al,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb bh,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + add bh,bh + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb bh,bh + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr ds:[3636H],dh + aaa + aaa + xor byte ptr [bx],bh + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bh + xor byte ptr [bx],dh + test word ptr ss:[bx+si],0ffH + add byte ptr [bx+si],al + add byte ptr [bx+si],al + inc word ptr [bx+si] + div word ptr ds:[3636H] + aaa + xor byte ptr [bx],dh + add byte ptr ss:[bx+si],al + inc word ptr [bx+si] + inc word ptr [bx+si] + add byte ptr [bx+si],al + test word ptr ss:[bx+si],36f7H + sbb byte ptr ss:[bx+si],bl + inc word ptr [bx+si] + inc word ptr [bx+si] + add byte ptr [bx+si],al + inc word ptr ss:[bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + inc word ptr [bx+si] + call dword ptr [bx+si] + sbb byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push word ptr ds:[3636H] + aas + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bl + sbb byte ptr [bx],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bh + push word ptr ss:[3636H] + sbb byte ptr [bx+si],bl + call dword ptr [bx+si] + call dword ptr [bx+si] + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + sbb byte ptr [bx+si],bl + clc + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx],bl + DB 18H +L$70: + sbb byte ptr [bx+si],bl + ???? + ???? + ???? + ???? + ???? + ???? + ???? + inc word ptr [bx+si] + add byte ptr [bx+si],al + add bh,bh + ???? + ???? + push ax + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + ???? + inc word ptr [bx+si] + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr -6cH[bp+si],ah + mov byte ptr 62H[si],dl + add al,dh + mov al,dh + mov byte ptr -7f10H[bx+si],cl + add al,bh + mov byte ptr -7f80H[bx+si],al + add byte ptr [bx+si],0 + cld + dec ax + dec ax + dec ax + dec ax + dec ax + add ah,bh + test byte ptr 20H[bx+si],al + inc ax + test ah,bh + add byte ptr [si],bh + inc ax + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + inc sp + inc sp + inc sp + js L$71 + inc ax + add byte ptr ds:[848H],dh + or byte ptr [bx+si],cl + or byte ptr [bx+si],al + cmp byte ptr [bx+si],dl + cmp byte ptr 44H[si],al + cmp byte ptr [bx+si],dl + cmp byte ptr -7cH[bx+si],bh + test ah,bh + test byte ptr 78H[si],al + js L$70 + test byte ptr 4848H[si],al + int 3 + add byte ptr 4[bx+si],bh + cmp byte ptr 44H[si],al + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + insb + xchg ax,dx + xchg ax,dx + insb + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,byte ptr 5aH[si] + and bl,byte ptr [si] + sbb byte ptr [bx+si],ah + inc ax + js L$73 + and byte ptr [bx+si],bl +L$71: + add byte ptr -7cH[bx+si],bh + test byte ptr -7b7cH[si],al + test byte ptr [bx+si],al + add ah,bh + add ah,bh + add ah,bh + add byte ptr [bx+si],al + and byte ptr [bx+si],ah + clc + and byte ptr [bx+si],ah + add al,bh + add byte ptr [bx+si],ah + adc byte ptr [bx+si],cl + adc byte ptr [bx+si],ah + add byte ptr [si],bh + or byte ptr [bx+si],dl + and byte ptr [bx+si],dl + or byte ptr [bx+si],al + jl L$72 +L$72: + or al,12H + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + adc byte ptr [bx+si],dl + nop + pusha + add byte ptr [bx+si],dl + add byte ptr [si],bh +L$73: + adc byte ptr [bx+si],al + add byte ptr [bx+si],al + xor cl,byte ptr [si] + xor cl,byte ptr [si] + add byte ptr [bx+si],bh + inc sp + inc sp + cmp byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + sbb byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],bl + add byte ptr [bx+si],al + add byte ptr ds:[808H],cl + or byte ptr 28H[bx+si],cl + sbb byte ptr [bx+si],cl + cmp byte ptr [si],ah + and al,24H + and al,0 + add byte ptr [bx+si],al + cmp al,4 + cmp al,20H + cmp al,0 + add byte ptr [bx+si],al + add byte ptr [bx+si],al + cmp al,3cH + cmp al,3cH + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al +L$74: + DW offset L$1 +L$75: + DB 8 +L$76: + add byte ptr [bx+si],cl + DB 0 +L$77: + DW offset L$1 +L$78: + DW seg L$1 +L$79: + or byte ptr [bx+si],al +L$80: + or byte ptr [bx+si],al +L$81: + or byte ptr [bx+si],al +L$82: + inc word ptr [bx+si] +L$83: + add byte ptr [bx+si],al +L$84: + or byte ptr [bx+si],al +L$85: + add byte ptr [bx+si],al +MXSETFONT: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 0cH[bp] + test ax,ax + jne L$87 + mov ax,word ptr 0aH[bp] + cmp ax,1 + jb L$86 + xor ax,ax +L$86: + shl ax,1 + shl ax,1 + mov bx,ax + mov ax,word ptr L$74[bx] + mov word ptr L$77,ax + mov word ptr L$78,cs + mov al,byte ptr L$75[bx] + xor ah,ah + mov word ptr L$79,ax + mov word ptr L$84,ax + mov dl,byte ptr L$76[bx] + xor dh,dh + mov word ptr L$80,dx + mul dx + mov word ptr L$81,ax + mov word ptr L$84,ax + xor ax,ax + mov word ptr L$85,ax + jmp L$88 +L$87: + mov ax,0ffffH + mov bx,word ptr 8[bp] + cmp bx,10H + ja L$88 + mov dx,word ptr 6[bp] + cmp dx,20H + ja L$88 + mov word ptr L$79,bx + mov word ptr L$80,dx + mov ax,bx + add ax,7 + shr ax,1 + shr ax,1 + shr ax,1 + mul dx + mov word ptr L$81,ax + mov ax,word ptr 0aH[bp] + mov word ptr L$77,ax + mov ax,word ptr 0cH[bp] + mov word ptr L$78,ax + xor ax,ax +L$88: + pop ds + mov sp,bp + pop bp + retf 8 +MXSETTEXTCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 8[bp] + mov word ptr L$82,ax + mov ax,word ptr 6[bp] + mov word ptr L$83,ax + xor ax,ax + pop ds + mov sp,bp + pop bp + retf 4 +MXOUTCHAR: + push bp + mov bp,sp + sub sp,202H + push ds + push si + push es + push di + lds si,dword ptr cs:L$77 + mov al,byte ptr 6[bp] + xor ah,ah + mul word ptr cs:L$81 + add si,ax + mov ax,ss + mov es,ax + lea di,-200H[bp] + mov dx,word ptr cs:L$82 + mov ax,word ptr cs:L$80 + mov word ptr -202H[bp],ax +L$89: + mov cx,word ptr cs:L$79 + mov bh,byte ptr [si] + inc si + cmp cx,8 + jbe L$90 + mov bl,byte ptr [si] + inc si +L$90: + mov al,dl + shl bx,1 + jb L$91 + mov al,dh +L$91: + mov byte ptr es:[di],al + inc di + dec cx + jne L$90 + dec word ptr -202H[bp] + jne L$89 + lea ax,-200H[bp] + push es + push ax + push word ptr 0aH[bp] + push word ptr 8[bp] + push word ptr cs:L$79 + push word ptr cs:L$80 + push word ptr cs:L$83 + push cs + call near ptr MX_TEXT:MXPUTIMAGE + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 6 +MXOUTTEXT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 6[bp] +L$92: + mov al,byte ptr [si] + test al,al + je L$93 + inc si + push word ptr 0cH[bp] + push word ptr 0aH[bp] + push ax + push cs + call near ptr MXOUTCHAR + mov ax,word ptr cs:L$84 + add word ptr 0cH[bp],ax + mov ax,word ptr cs:L$85 + add word ptr 0aH[bp],ax + dec word ptr -202H[bp] + jne L$92 +L$93: + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 + retf +MXSETTEXTSTEP: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr 8[bp] + mov word ptr L$84,ax + mov ax,word ptr 6[bp] + mov word ptr L$85,ax + pop ds + mov sp,bp + pop bp + retf 4 +MXGETTEXTSTEP: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr cs:L$84 + lds si,dword ptr 0aH[bp] + mov word ptr [si],ax + mov ax,word ptr cs:L$85 + lds si,dword ptr 6[bp] + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxot_.asm b/16/xw__/mxot_.asm new file mode 100755 index 00000000..e431b138 --- /dev/null +++ b/16/xw__/mxot_.asm @@ -0,0 +1,333 @@ +;----------------------------------------------------------- +; +; MXOT.ASM - Text functions +; Copyright (c) 1994 by Alessandro Scotti +; +;----------------------------------------------------------- +;WARN PRO +;NOWARN RES ; We use the reserved name 'WIDTH' +INCLUDE MODEX.DEF + +PUBLIC mxOutChar +PUBLIC mxOutText +PUBLIC mxSetFont +PUBLIC mxSetTextColor +PUBLIC mxGetTextStep +PUBLIC mxSetTextStep + +MAX_WIDTH EQU 16 ; Must be <= 16 +MAX_HEIGHT EQU 32 + +MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' + ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING + +EXTRN mx_CodeSegment : WORD +EXTRN mxPutImage : FAR + +; Default 8x8 font +fnt_Default LABEL BYTE + INCLUDE DEFAULT.FNT + +; Table of system fonts +tbl_SystemFont LABEL WORD + DW fnt_Default, 8, 8 + +MX_MAXSYSFONT EQU ($-OFFSET tbl_SystemFont) SHR 2 + +mx_FontPtr DW OFFSET fnt_Default, SEG MX_TEXT +mx_FontWidth DW 8 ; Font width in pixels +mx_FontHeight DW 8 ; Font height in pixels +mx_FontCharSize DW 8 ; Size in bytes of a font character +mx_FontColor DW 00FFh ; Color: foreground + background*256 +mx_FontOp DW OP_MOVE ; Raster op +mx_DeltaX DW 8 ; Horizontal step +mx_DeltaY DW 0 ; Vertical step + +;----------------------------------------------------------- +; +; Sets the current font. +; +; Input: +; Font = pointer to font data +; Width = width of font character in pixels +; Height = height of font character in pixels +; Output: +; AX = 0 on success, else invalid parameters +; +; Note: when the high word of Font (i.e. the segment) is zero, the low +; word is used to select one of the system fonts. +; +mxSetFont PROC FAR + push bp + mov bp,sp + sub sp,0 + push ds + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, WORD PTR Font[2] ; Get font segment + test ax, ax ; Null segment? + jnz @@UserFont ; No, install user font + +; Install system font + mov ax, WORD PTR Font[0] ; Get font number + cmp ax, MX_MAXSYSFONT ; Check range + jb @@SystemFont + xor ax, ax ; Out of range, use default font +@@SystemFont: + shl ax, 1 + shl ax, 1 + mov bx, ax + mov ax, tbl_SystemFont[bx] ; Get font offset + mov WORD PTR mx_FontPtr[0], ax + mov WORD PTR mx_FontPtr[2], cs + mov al, BYTE PTR tbl_SystemFont[bx+2] + xor ah, ah + mov [mx_FontWidth], ax + mov [mx_DeltaX], ax + mov dl, BYTE PTR tbl_SystemFont[bx+3] + xor dh, dh + mov [mx_FontHeight], dx + mul dx + mov [mx_FontCharSize], ax + mov [mx_DeltaX], ax + xor ax, ax + mov [mx_DeltaY], ax + jmp @@Exit + +; Install user font +@@UserFont: + mov ax, -1 ; Assume an error + mov bx, [bp+8] + cmp bx, MAX_WIDTH + ja @@Exit ; Invalid character width + mov dx, [bp+4] + cmp dx, MAX_HEIGHT + ja @@Exit ; Invalid character height + mov [mx_FontWidth], bx + mov [mx_FontHeight], dx + mov ax, bx + add ax, 7 + shr ax, 1 + shr ax, 1 + shr ax, 1 + mul dx + mov [mx_FontCharSize], ax + mov ax, WORD PTR Font[0] + mov WORD PTR mx_FontPtr[0], ax + mov ax, WORD PTR Font[2] + mov WORD PTR mx_FontPtr[2], ax + xor ax, ax + +@@Exit: + .pop ds + ASSUME ds:NOTHING + ;.leave ARG_SIZE +mxSetFont ENDP + +;----------------------------------------------------------- +; +; Sets the text color and raster op. +; +; Input: +; Color = text color (foreground + background*256) +; Op = raster op +; Output: +; none +; +mxSetTextColor PROC FAR + ARG Op:WORD, \ + Color:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [Color] + mov [mx_FontColor], ax + mov ax, [Op] + mov [mx_FontOp], ax + + xor ax, ax + .pop ds + ASSUME ds:NOTHING + .leave ARG_SIZE +mxSetTextColor ENDP + +;----------------------------------------------------------- +; +; Writes a character using the current font and attributes. +; +; Input: +; X, Y = video coordinates +; C = character to print +; Output: +; none +; +mxOutChar PROC FAR + ARG C:BYTE:2, \ + Y:WORD, \ + X:WORD = ARG_SIZE + LOCAL Image:BYTE:MAX_WIDTH*MAX_HEIGHT, \ + Count:WORD = AUTO_SIZE + .enter AUTO_SIZE + .push ds, si, es, di + ASSUME ds:NOTHING + +; Gets the pointer to font data for the selected character + lds si, DWORD PTR [mx_FontPtr] + mov al, [C] + xor ah, ah + mul [mx_FontCharSize] ; Offset into font + add si, ax ; DS:SI -> font data for character + +; Converts font data into a 256-color linear image + mov ax, ss + mov es, ax + lea di, [Image] + mov dx, [mx_FontColor] + mov ax, [mx_FontHeight] + mov [Count], ax +@@HeightLoop: + mov cx, [mx_FontWidth] + mov bh, ds:[si] + inc si ; Get a byte from font data + cmp cx, 8 + jbe @@WidthLoop ; Ok for width <= 8 + mov bl, ds:[si] ; Get another byte + inc si +@@WidthLoop: + mov al, dl ; Assume foreground color + shl bx, 1 ; Is font bit set? + jc @@1 ; Yes, foreground is just great + mov al, dh ; Get background color +@@1: + mov es:[di], al ; Put pixel into image + inc di + dec cx + jnz @@WidthLoop + dec [Count] + jnz @@HeightLoop + +; Now pass image to mx_PutImage + lea ax, [Image] + push es + push ax ; Pointer to image + push [X] + push [Y] ; Image coordinates + push [mx_FontWidth] + push [mx_FontHeight] ; Image size + push [mx_FontOp] ; Raster op + call mxPutImage ; Write character + + xor ax, ax + .pop ds, si, es, di + .leave ARG_SIZE +mxOutChar ENDP + +;----------------------------------------------------------- +; +; Writes a string at the coordinates specified. +; +; Input: +; X, Y = text coordinates +; S = pointer to ASCIIZ string +; Output: +; none +; +mxOutText PROC FAR + ARG S:DWORD, \ + Y:WORD, \ + X:WORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + lds si, [S] +@@Loop: + mov al, ds:[si] + test al, al ; End of string? + jz @@Exit ; Yes, exit + inc si + push [X] ; Display character + push [Y] + push ax + call mxOutChar + mov ax, [mx_DeltaX] + add [X], ax ; Bump X coordinate + mov ax, [mx_DeltaY] + add [Y], ax ; Bump Y coordinate + dec [Count] + jnz @@Loop + +@@Exit: + xor ax, ax + .pop ds, si + .leave ARG_SIZE + ret +mxOutText ENDP + +;----------------------------------------------------------- +; +; Sets the distance between characters. +; +; Input: +; DeltaX = horizontal distance in pixels +; DeltaY = vertical distance in pixels +; Output: +; none +; +; Note: this function may be used to set the text direction. +; +mxSetTextStep PROC FAR + ARG DeltaY:WORD, \ + DeltaX:WORD = ARG_SIZE + .enter 0 + .push ds + + mov ds, [mx_CodeSegment] + ASSUME ds:MX_TEXT + + mov ax, [DeltaX] + mov [mx_DeltaX], ax + mov ax, [DeltaY] + mov [mx_DeltaY], ax + + .pop ds + .leave ARG_SIZE +mxSetTextStep ENDP + +;----------------------------------------------------------- +; +; Gets the current distance between characters. +; +; Input: +; DeltaX = pointer to horizontal distance in pixels (integer) +; DeltaY = pointer to vertical distance in pixels (integer) +; Output: +; none +; +mxGetTextStep PROC FAR + ARG DeltaY:DWORD, \ + DeltaX:DWORD = ARG_SIZE + .enter 0 + .push ds, si + ASSUME ds:NOTHING + + mov ax, [mx_DeltaX] + lds si, [DeltaX] + mov ds:[si], ax + mov ax, [mx_DeltaY] + lds si, [DeltaY] + mov ds:[si], ax + + .pop ds, si + .leave ARG_SIZE +mxGetTextStep ENDP + +MX_TEXT ENDS +END diff --git a/16/xw__/mxpb.asm b/16/xw__/mxpb.asm new file mode 100755 index 00000000..36ed3527 --- /dev/null +++ b/16/xw__/mxpb.asm @@ -0,0 +1,4103 @@ +.387 + PUBLIC MX_SCANBUFFER +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_SCANBUFFER: + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al + add byte ptr [bx+si],al +MX_TEXT ENDS + END diff --git a/16/xw__/mxpf.asm b/16/xw__/mxpf.asm new file mode 100755 index 00000000..3777fe5e --- /dev/null +++ b/16/xw__/mxpf.asm @@ -0,0 +1,328 @@ +.387 + PUBLIC MXFILLPOLY + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_SCANBUFFER:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov cx,word ptr [si] + sub cx,word ptr [bx] + jg L$2 + ret +L$2: + push bp + mov ax,word ptr 2[si] + mov bx,word ptr 2[bx] + sub ax,bx + jg L$4 + jl L$6 + mov ax,bx +L$3: + mov word ptr es:[di],ax + add di,4 + dec cx + jne L$3 + jmp L$8 +L$4: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$5: + mov word ptr es:[di],ax + add di,4 + add dx,bx + adc ax,bp + dec cx + jne L$5 + jmp L$8 +L$6: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$7: + mov word ptr es:[di],ax + add di,4 + sub dx,bx + sbb ax,bp + dec cx + jne L$7 +L$8: + pop bp + ret +MXFILLPOLY: + push bp + mov bp,sp + sub sp,1eH + push ds + push si + push es + push di + mov cx,word ptr 10H[bp] + cmp cx,3 + jae L$9 + jmp near ptr L$36 +L$9: + les di,dword ptr 0cH[bp] + lds si,dword ptr 8[bp] + mov word ptr -16H[bp],7fffH + mov word ptr -1aH[bp],8000H + mov word ptr -18H[bp],7fffH + mov word ptr -1eH[bp],8000H + xor dx,dx +L$10: + mov bx,word ptr es:[di] + shl bx,1 + shl bx,1 + add bx,si + mov ax,word ptr [bx] + cmp ax,word ptr -16H[bp] + jge L$11 + mov word ptr -16H[bp],ax + mov word ptr -0eH[bp],dx + mov word ptr -10H[bp],dx +L$11: + cmp ax,word ptr -1aH[bp] + jle L$12 + mov word ptr -1aH[bp],ax + mov word ptr -12H[bp],dx +L$12: + mov ax,word ptr 2[bx] + cmp ax,word ptr -18H[bp] + jge L$13 + mov word ptr -18H[bp],ax +L$13: + cmp ax,word ptr -1eH[bp] + jle L$14 + mov word ptr -1eH[bp],ax +L$14: + inc di + inc dx + inc di + inc dx + dec cx + jne L$10 + mov ax,word ptr -1aH[bp] + cmp ax,word ptr cs:MX_CLIPX1 + jge L$15 + jmp near ptr L$36 +L$15: + mov bx,word ptr -16H[bp] + cmp bx,word ptr cs:MX_CLIPX2 + jle L$16 + jmp near ptr L$36 +L$16: + sub ax,bx + jg L$17 + jmp near ptr L$36 +L$17: + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jge L$18 + jmp near ptr L$36 +L$18: + mov bx,word ptr -18H[bp] + cmp bx,word ptr cs:MX_CLIPY2 + jle L$19 + jmp near ptr L$36 +L$19: + sub ax,bx + jg L$20 + jmp near ptr L$36 +L$20: + dec word ptr 10H[bp] + shl word ptr 10H[bp],1 + mov es,word ptr cs:MX_CODESEGMENT + mov ax,offset MX_TEXT:MX_SCANBUFFER + mov word ptr -4[bp],ax + mov si,word ptr -0eH[bp] +L$21: + lds bx,dword ptr 0cH[bp] + mov di,word ptr [bx+si] + dec si + dec si + test si,si + jge L$22 + mov si,word ptr 10H[bp] +L$22: + mov word ptr -0eH[bp],si + mov si,word ptr [bx+si] + shl di,1 + shl di,1 + shl si,1 + shl si,1 + lds bx,dword ptr 8[bp] + add si,bx + add bx,di + mov di,word ptr -4[bp] + call near ptr L$1 + mov word ptr -4[bp],di + mov si,word ptr -0eH[bp] + cmp si,word ptr -12H[bp] + jne L$21 + mov ax,offset MX_TEXT:MX_SCANBUFFER+2 + mov word ptr -6[bp],ax + mov si,word ptr -10H[bp] +L$23: + lds bx,dword ptr 0cH[bp] + mov di,word ptr [bx+si] + inc si + inc si + cmp si,word ptr 10H[bp] + jbe L$24 + xor si,si +L$24: + mov word ptr -10H[bp],si + mov si,word ptr [bx+si] + shl di,1 + shl di,1 + shl si,1 + shl si,1 + lds bx,dword ptr 8[bp] + add si,bx + add bx,di + mov di,word ptr -6[bp] + call near ptr L$1 + mov word ptr -6[bp],di + mov si,word ptr -10H[bp] + cmp si,word ptr -12H[bp] + jne L$23 + mov si,offset MX_TEXT:MX_SCANBUFFER + mov ax,word ptr -16H[bp] + mov cx,word ptr -1aH[bp] + sub cx,ax + mov bx,word ptr cs:MX_CLIPX1 + sub bx,ax + jle L$25 + sub cx,bx + add ax,bx + mov word ptr -16H[bp],ax + shl bx,1 + shl bx,1 + add si,bx +L$25: + mov bx,ax + add bx,cx + sub bx,word ptr cs:MX_CLIPX2 + jle L$26 + sub cx,bx +L$26: + test cx,cx + jg L$27 + jmp near ptr L$36 +L$27: + mov word ptr -8[bp],cx + mov word ptr -4[bp],si + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr -18H[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$28 + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY2 + jg L$28 + jmp L$32 +L$28: + mov di,cx + inc di + sub si,4 +L$29: + dec di + je L$32 + add si,4 + mov ax,word ptr [si] + mov cx,word ptr 2[si] + mov dx,word ptr cs:MX_CLIPY2 + cmp ax,dx + jg L$31 + cmp cx,dx + jle L$30 + mov word ptr 2[si],dx + mov bx,cx + sub bx,dx + sub cx,ax + jle L$31 + mov cx,word ptr 2[si] +L$30: + mov dx,word ptr cs:MX_CLIPY1 + cmp cx,dx + jl L$31 + sub cx,ax + jle L$31 + cmp ax,dx + jge L$29 + mov word ptr [si],dx + sub dx,ax + cmp cx,dx + ja L$29 +L$31: + mov word ptr [si],0ffffH + jmp L$29 +L$32: + mov es,word ptr cs:MX_VIDEOSEGMENT + mov si,word ptr -4[bp] + mov cl,byte ptr -16H[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -2[bp],al + shr word ptr -16H[bp],1 + shr word ptr -16H[bp],1 +L$33: + mov ax,word ptr [si] + test ax,ax + js L$35 + mov cx,word ptr 2[si] + sub cx,ax + jle L$35 + mul word ptr cs:MX_BYTESPERLINE + add ax,word ptr -16H[bp] + mov di,ax + mov ah,byte ptr -2[bp] + mov dx,3c4H + mov al,2 + out dx,ax + mov ax,word ptr 6[bp] + mov dx,word ptr cs:MX_BYTESPERLINE + shr cx,1 + jae L$34 + mov byte ptr es:[di],al + add di,dx + jcxz L$35 +L$34: + mov byte ptr es:[di],al + add di,dx + mov byte ptr es:[di],al + add di,dx + dec cx + jne L$34 +L$35: + rol byte ptr -2[bp],1 + adc word ptr -16H[bp],0 + add si,4 + dec word ptr -8[bp] + jne L$33 +L$36: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw__/mxpg.asm b/16/xw__/mxpg.asm new file mode 100755 index 00000000..7318f079 --- /dev/null +++ b/16/xw__/mxpg.asm @@ -0,0 +1,458 @@ +.387 + PUBLIC MXGOURAUDPOLY + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_SCANBUFFER:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + mov cx,word ptr [si] + sub cx,word ptr [bx] + jg L$2 + ret +L$2: + push bp + push di + push cx + push ax + push dx + mov ax,word ptr 2[si] + mov bx,word ptr 2[bx] + sub ax,bx + jg L$4 + jl L$6 + mov ax,bx +L$3: + mov word ptr es:[di],ax + add di,8 + dec cx + jne L$3 + jmp L$8 +L$4: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$5: + mov word ptr es:[di],ax + add di,8 + add dx,bx + adc ax,bp + dec cx + jne L$5 + jmp L$8 +L$6: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$7: + mov word ptr es:[di],ax + add di,8 + sub dx,bx + sbb ax,bp + dec cx + jne L$7 +L$8: + pop bx + pop ax + pop cx + pop di + sub ax,bx + jg L$10 + jl L$12 + mov ah,bl + mov al,80H +L$9: + mov word ptr es:2[di],ax + add di,8 + dec cx + jne L$9 + jmp L$14 +L$10: + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$11: + mov byte ptr es:3[di],al + mov byte ptr es:2[di],dh + add di,8 + add dx,bx + adc ax,bp + dec cx + jne L$11 + jmp L$14 +L$12: + neg ax + cwd + div cx + mov bp,ax + xor ax,ax + div cx + xchg ax,bx + mov dx,8000H +L$13: + mov byte ptr es:3[di],al + mov byte ptr es:2[di],dh + add di,8 + sub dx,bx + sbb ax,bp + dec cx + jne L$13 +L$14: + pop bp + ret +L$15: + mov ax,word ptr 6[si] + mov bx,word ptr 2[si] + cmp ah,bh + jg L$17 + jl L$19 + add ax,dx + mov dx,word ptr cs:MX_BYTESPERLINE +L$16: + mov byte ptr es:[di],ah + add di,dx + dec cx + jne L$16 + ret +L$17: + push bp + push si + mov si,bx + add si,dx + sub ax,bx + xor dx,dx + div cx + mov bp,ax + xor ax,ax + div cx + mov bx,ax + mov dx,8000H + mov ax,word ptr cs:MX_BYTESPERLINE + xchg ax,si +L$18: + mov byte ptr es:[di],ah + add dx,bx + adc ax,bp + add di,si + dec cx + jne L$18 + pop si + pop bp + ret +L$19: + push bp + push si + mov si,bx + add si,dx + sub ax,bx + neg ax + xor dx,dx + div cx + mov bp,ax + xor ax,ax + div cx + mov bx,ax + mov dx,8000H + mov ax,word ptr cs:MX_BYTESPERLINE + xchg ax,si +L$20: + mov byte ptr es:[di],ah + sub dx,bx + sbb ax,bp + add di,si + dec cx + jne L$20 + pop si + pop bp + ret +MXGOURAUDPOLY: + push bp + mov bp,sp + sub sp,1eH + push ds + push si + push es + push di + mov cx,word ptr 14H[bp] + cmp cx,3 + jae L$21 + jmp near ptr L$47 +L$21: + les di,dword ptr 10H[bp] + lds si,dword ptr 0cH[bp] + mov word ptr -16H[bp],7fffH + mov word ptr -1aH[bp],8000H + mov word ptr -18H[bp],7fffH + mov word ptr -1eH[bp],8000H + xor dx,dx +L$22: + mov bx,word ptr es:[di] + shl bx,1 + shl bx,1 + add bx,si + mov ax,word ptr [bx] + cmp ax,word ptr -16H[bp] + jge L$23 + mov word ptr -16H[bp],ax + mov word ptr -0eH[bp],dx + mov word ptr -10H[bp],dx +L$23: + cmp ax,word ptr -1aH[bp] + jle L$24 + mov word ptr -1aH[bp],ax + mov word ptr -12H[bp],dx +L$24: + mov ax,word ptr 2[bx] + cmp ax,word ptr -18H[bp] + jge L$25 + mov word ptr -18H[bp],ax +L$25: + cmp ax,word ptr -1eH[bp] + jle L$26 + mov word ptr -1eH[bp],ax +L$26: + inc di + inc di + inc dx + inc dx + dec cx + jne L$22 + mov ax,word ptr -1aH[bp] + cmp ax,word ptr cs:MX_CLIPX1 + jge L$27 + jmp near ptr L$47 +L$27: + mov bx,word ptr -16H[bp] + cmp bx,word ptr cs:MX_CLIPX2 + jle L$28 + jmp near ptr L$47 +L$28: + sub ax,bx + jg L$29 + jmp near ptr L$47 +L$29: + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jge L$30 + jmp near ptr L$47 +L$30: + mov bx,word ptr -18H[bp] + cmp bx,word ptr cs:MX_CLIPY2 + jle L$31 + jmp near ptr L$47 +L$31: + sub ax,bx + jg L$32 + jmp near ptr L$47 +L$32: + dec word ptr 14H[bp] + shl word ptr 14H[bp],1 + mov es,word ptr cs:MX_CODESEGMENT + mov ax,offset MX_TEXT:MX_SCANBUFFER + mov word ptr -4[bp],ax + mov si,word ptr -0eH[bp] +L$33: + lds bx,dword ptr 10H[bp] + mov di,word ptr [bx+si] + dec si + dec si + test si,si + jge L$34 + mov si,word ptr 14H[bp] +L$34: + mov word ptr -0eH[bp],si + mov si,word ptr [bx+si] + lds bx,dword ptr 8[bp] + shl di,1 + shl si,1 + mov ax,word ptr [bx+si] + mov dx,word ptr [bx+di] + lds bx,dword ptr 0cH[bp] + shl si,1 + shl di,1 + add si,bx + add bx,di + mov di,word ptr -4[bp] + call near ptr L$1 + mov word ptr -4[bp],di + mov si,word ptr -0eH[bp] + cmp si,word ptr -12H[bp] + jne L$33 + mov ax,offset MX_TEXT:MX_SCANBUFFER+4 + mov word ptr -6[bp],ax + mov si,word ptr -10H[bp] +L$35: + lds bx,dword ptr 10H[bp] + mov di,word ptr [bx+si] + inc si + inc si + cmp si,word ptr 14H[bp] + jbe L$36 + xor si,si +L$36: + mov word ptr -10H[bp],si + mov si,word ptr [bx+si] + lds bx,dword ptr 8[bp] + shl di,1 + shl si,1 + mov ax,word ptr [bx+si] + mov dx,word ptr [bx+di] + lds bx,dword ptr 0cH[bp] + shl si,1 + shl di,1 + add si,bx + add bx,di + mov di,word ptr -6[bp] + call near ptr L$1 + mov word ptr -6[bp],di + mov si,word ptr -10H[bp] + cmp si,word ptr -12H[bp] + jne L$35 + mov si,offset MX_TEXT:MX_SCANBUFFER + mov ax,word ptr -16H[bp] + mov cx,word ptr -1aH[bp] + sub cx,ax + mov bx,word ptr cs:MX_CLIPX1 + sub bx,ax + jle L$37 + sub cx,bx + add ax,bx + mov word ptr -16H[bp],ax + shl bx,1 + shl bx,1 + shl bx,1 + add si,bx +L$37: + mov bx,ax + add bx,cx + sub bx,word ptr cs:MX_CLIPX2 + jle L$38 + sub cx,bx +L$38: + test cx,cx + jg L$39 + jmp near ptr L$47 +L$39: + mov word ptr -8[bp],cx + mov word ptr -4[bp],si + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,word ptr -18H[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$40 + mov ax,word ptr -1eH[bp] + cmp ax,word ptr cs:MX_CLIPY2 + jg L$40 + jmp L$44 +L$40: + mov di,cx + inc di + sub si,8 +L$41: + dec di + je L$44 + add si,8 + mov ax,word ptr [si] + mov cx,word ptr 4[si] + mov dx,word ptr cs:MX_CLIPY2 + cmp ax,dx + jg L$43 + cmp cx,dx + jle L$42 + mov word ptr 4[si],dx + mov bx,cx + sub bx,dx + sub cx,ax + jle L$43 + mov ax,word ptr 2[si] + sub ax,word ptr 6[si] + imul bx + idiv cx + add word ptr 6[si],ax + mov ax,word ptr [si] + mov cx,word ptr 4[si] +L$42: + mov dx,word ptr cs:MX_CLIPY1 + cmp cx,dx + jl L$43 + sub cx,ax + jle L$43 + cmp ax,dx + jge L$41 + mov word ptr [si],dx + sub dx,ax + cmp cx,dx + jbe L$43 + mov ax,word ptr 6[si] + sub ax,word ptr 2[si] + imul dx + idiv cx + add word ptr 2[si],ax + jmp L$41 +L$43: + mov word ptr [si],0ffffH + jmp L$41 +L$44: + mov es,word ptr cs:MX_VIDEOSEGMENT + mov si,word ptr -4[bp] + mov cl,byte ptr -16H[bp] + and cl,3 + mov al,11H + shl al,cl + mov byte ptr -2[bp],al + shr word ptr -16H[bp],1 + shr word ptr -16H[bp],1 + mov ax,word ptr 6[bp] + mov ah,al + xor al,al + mov word ptr 6[bp],ax +L$45: + mov ax,word ptr [si] + test ax,ax + js L$46 + mov cx,word ptr 4[si] + sub cx,ax + jle L$46 + mul word ptr cs:MX_BYTESPERLINE + add ax,word ptr -16H[bp] + mov di,ax + mov ah,byte ptr -2[bp] + mov al,2 + mov dx,3c4H + out dx,ax + mov dx,word ptr 6[bp] + call near ptr L$15 +L$46: + rol byte ptr -2[bp],1 + adc word ptr -16H[bp],0 + add si,8 + dec word ptr -8[bp] + jne L$45 +L$47: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 10H +MX_TEXT ENDS + END diff --git a/16/xw__/mxpi.asm b/16/xw__/mxpi.asm new file mode 100755 index 00000000..3484a58d --- /dev/null +++ b/16/xw__/mxpi.asm @@ -0,0 +1,219 @@ +.387 + PUBLIC MXPUTIMAGE + EXTRN SUBCLIPIMAGE:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$2 + DW offset L$6 + DW offset L$10 + DW offset L$14 + DW offset L$18 + DW offset L$20 +L$2: + shr cx,1 + jb L$5 +L$3: + movsb + add si,3 + movsb + add si,3 + dec cx + jne L$3 +L$4: + ret +L$5: + movsb + add si,3 + jcxz L$4 + jmp L$3 +L$6: + shr cx,1 + jb L$9 +L$7: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + and word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$7 +L$8: + ret +L$9: + lodsb + and byte ptr es:[di],al + inc di + add si,3 + jcxz L$8 + jmp L$7 +L$10: + shr cx,1 + jb L$13 +L$11: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + or word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$11 +L$12: + ret +L$13: + lodsb + or byte ptr es:[di],al + inc di + add si,3 + jcxz L$12 + jmp L$11 +L$14: + shr cx,1 + jb L$17 +L$15: + mov al,byte ptr [si] + mov ah,byte ptr 4[si] + xor word ptr es:[di],ax + inc di + inc di + add si,8 + dec cx + jne L$15 +L$16: + ret +L$17: + lodsb + xor byte ptr es:[di],al + inc di + add si,3 + jcxz L$16 + jmp L$15 +L$18: + mov al,byte ptr [si] + cmp al,ah + je L$19 + mov byte ptr es:[di],al +L$19: + inc di + add si,4 + dec cx + jne L$18 + ret +L$20: + mov al,byte ptr [si] + add byte ptr es:[di],al + inc di + add si,4 + dec cx + jne L$20 + ret +MXPUTIMAGE: + push bp + mov bp,sp + sub sp,14H + push ds + push si + push es + push di + mov bx,word ptr 0eH[bp] + mov ax,word ptr 0cH[bp] + mov cx,word ptr 0aH[bp] + mov dx,word ptr 8[bp] + call near ptr MX_TEXT:SUBCLIPIMAGE + jae L$21 + jmp near ptr L$26 +L$21: + mov word ptr 8[bp],dx + add word ptr 10H[bp],si + mul word ptr cs:MX_BYTESPERLINE + mov di,bx + shr di,1 + shr di,1 + add di,ax + mov word ptr -0aH[bp],di + mov es,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -10H[bp],bl + mov bx,cx + shr bx,1 + shr bx,1 + and cl,3 + mov al,8 + shr al,cl + mov si,6 +L$22: + mov word ptr -8[bp+si],bx + shr al,1 + adc bx,0 + dec si + dec si + jge L$22 + mov cl,byte ptr -10H[bp] + mov al,11H + shl al,cl + mov byte ptr -14H[bp],al + mov bx,word ptr 6[bp] + mov byte ptr -12H[bp],bh + xor bh,bh + cmp bl,5 + jbe L$23 + xor bl,bl +L$23: + shl bx,1 + mov ax,word ptr cs:L$1[bx] + mov word ptr -0cH[bp],ax + cld + mov byte ptr -0eH[bp],4 + lea bx,-8[bp] + mov ds,word ptr 12H[bp] +L$24: + cmp word ptr ss:[bx],0 + je L$26 + mov si,word ptr 10H[bp] + mov ah,byte ptr -14H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -10H[bp] + and ah,3 + mov al,4 + mov dx,3ceH + out dx,ax + mov dx,word ptr 8[bp] + mov di,word ptr -0aH[bp] +L$25: + push si + push di + mov cx,word ptr ss:[bx] + mov ah,byte ptr -12H[bp] + call word ptr -0cH[bp] + pop di + pop si + add si,word ptr 0aH[bp] + add di,word ptr cs:MX_BYTESPERLINE + dec dx + jne L$25 + inc bx + inc bx + inc byte ptr -10H[bp] + rol byte ptr -14H[bp],1 + adc word ptr -0aH[bp],0 + inc word ptr 10H[bp] + dec byte ptr -0eH[bp] + jne L$24 +L$26: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0eH +MX_TEXT ENDS + END diff --git a/16/xw__/mxpn.asm b/16/xw__/mxpn.asm new file mode 100755 index 00000000..7b60449d --- /dev/null +++ b/16/xw__/mxpn.asm @@ -0,0 +1,35 @@ +.387 + PUBLIC MXPAN + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MXWAITDISPLAY:BYTE + EXTRN MXSTARTADDRESS:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXPAN: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + mov dx,word ptr 8[bp] + shr dx,1 + shr dx,1 + add ax,dx + push ax + call far ptr MXWAITDISPLAY + call far ptr MXSTARTADDRESS + mov dx,3daH + in al,dx + mov dx,3c0H + mov al,33H + out dx,al + mov al,byte ptr 8[bp] + and al,3 + shl al,1 + out dx,al + xor ax,ax + mov sp,bp + pop bp + retf 4 +MX_TEXT ENDS + END diff --git a/16/xw__/mxpp.asm b/16/xw__/mxpp.asm new file mode 100755 index 00000000..d15387eb --- /dev/null +++ b/16/xw__/mxpp.asm @@ -0,0 +1,85 @@ +.387 + PUBLIC MXGETPIXEL + PUBLIC MXPUTPIXEL + EXTRN MX_CLIPX1:BYTE + EXTRN MX_CLIPX2:BYTE + EXTRN MX_CLIPY1:BYTE + EXTRN MX_CLIPY2:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXGETPIXEL: + push bp + mov bp,sp + sub sp,0 + push ds + push si + xor ax,ax + mov si,word ptr 8[bp] + cmp si,word ptr cs:MX_CLIPX1 + jl L$1 + cmp si,word ptr cs:MX_CLIPX2 + jg L$1 + mov bx,word ptr 6[bp] + cmp bx,word ptr cs:MX_CLIPY1 + jl L$1 + cmp bx,word ptr cs:MX_CLIPY2 + jg L$1 + mov al,4 + mov ah,byte ptr 8[bp] + and ah,3 + mov dx,3ceH + out dx,ax + mov ds,word ptr cs:MX_VIDEOSEGMENT + mov ax,bx + mul word ptr cs:MX_BYTESPERLINE + shr si,1 + shr si,1 + add si,ax + mov al,byte ptr [si] + xor ah,ah +L$1: + pop si + pop ds + mov sp,bp + pop bp + retf 4 +MXPUTPIXEL: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov si,word ptr 0aH[bp] + cmp si,word ptr cs:MX_CLIPX1 + jl L$2 + cmp si,word ptr cs:MX_CLIPX2 + jg L$2 + mov ax,word ptr 8[bp] + cmp ax,word ptr cs:MX_CLIPY1 + jl L$2 + cmp ax,word ptr cs:MX_CLIPY2 + jg L$2 + mov ds,word ptr cs:MX_VIDEOSEGMENT + mul word ptr cs:MX_BYTESPERLINE + shr si,1 + shr si,1 + add si,ax + mov cl,byte ptr 0aH[bp] + and cl,3 + mov ax,102H + shl ah,cl + mov dx,3c4H + out dx,ax + mov al,byte ptr 6[bp] + mov byte ptr [si],al +L$2: + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 6 +MX_TEXT ENDS + END diff --git a/16/xw__/mxra.asm b/16/xw__/mxra.asm new file mode 100755 index 00000000..539f4ee7 --- /dev/null +++ b/16/xw__/mxra.asm @@ -0,0 +1,18 @@ +.387 + PUBLIC MXROWADDRESS +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXROWADDRESS: + push bp + mov bp,sp + sub sp,0 + mov dx,3d4H + mov al,13H + mov ah,byte ptr 6[bp] + out dx,ax + xor ax,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxrp.asm b/16/xw__/mxrp.asm new file mode 100755 index 00000000..be508c59 --- /dev/null +++ b/16/xw__/mxrp.asm @@ -0,0 +1,73 @@ +.387 + PUBLIC MXROTATEPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXROTATEPALETTE: + push bp + mov bp,sp + sub sp,300H + push ds + push si + push es + push di + mov bx,word ptr 8[bp] + add bx,bx + add bx,word ptr 8[bp] + lds si,dword ptr 0aH[bp] + push ss + pop es + lea di,-300H[bp] + cld + mov ax,word ptr 6[bp] + mov dx,ax + test ax,ax + je L$2 + jl L$1 + add ax,ax + add dx,ax + sub bx,dx + add si,bx + push si + mov cx,dx + rep movsb + mov es,word ptr 0cH[bp] + mov di,si + dec di + pop si + dec si + mov cx,bx + std + rep movsb + push ss + pop ds + lea si,-300H[bp] + les di,dword ptr 0aH[bp] + mov cx,dx + cld + rep movsb + jmp L$2 +L$1: + add ax,ax + add dx,ax + neg dx + sub bx,dx + mov cx,dx + rep movsb + les di,dword ptr 0aH[bp] + mov cx,bx + rep movsb + push ss + pop ds + lea si,-300H[bp] + mov cx,dx + rep movsb +L$2: + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxsa.asm b/16/xw__/mxsa.asm new file mode 100755 index 00000000..8504fa95 --- /dev/null +++ b/16/xw__/mxsa.asm @@ -0,0 +1,23 @@ +.387 + PUBLIC MXSTARTADDRESS +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSTARTADDRESS: + push bp + mov bp,sp + sub sp,0 + mov bx,word ptr 6[bp] + mov dx,3d4H + mov al,0cH + mov ah,bh + cli + out dx,ax + mov al,0dH + mov ah,bl + out dx,ax + sti + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxsc.asm b/16/xw__/mxsc.asm new file mode 100755 index 00000000..e65d8460 --- /dev/null +++ b/16/xw__/mxsc.asm @@ -0,0 +1,27 @@ +.387 + PUBLIC MXSETCOLOR +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSETCOLOR: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr 0cH[bp] + mov dx,3c8H + out dx,al + inc dx + mov al,byte ptr 0aH[bp] + out dx,al + mov al,byte ptr 8[bp] + out dx,al + mov al,byte ptr 6[bp] + out dx,al + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxsi.asm b/16/xw__/mxsi.asm new file mode 100755 index 00000000..a9179a88 --- /dev/null +++ b/16/xw__/mxsi.asm @@ -0,0 +1,221 @@ +.387 + PUBLIC MXSTRETCHIMAGE + EXTRN SUBCLIPBOX:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + DW offset L$8 + DW offset L$10 + DW offset L$12 + DW offset L$14 + DW offset L$16 + DW offset L$19 +MXSTRETCHIMAGE: + push bp + mov bp,sp + sub sp,14H + push ds + push si + push es + push di + xor dx,dx + mov ax,word ptr 0eH[bp] + mov bx,word ptr 0aH[bp] + div bx + mov word ptr -0aH[bp],ax + xor ax,ax + div bx + mov word ptr -0cH[bp],ax + xor dx,dx + mov ax,word ptr 0cH[bp] + mov bx,word ptr 8[bp] + div bx + mov word ptr -0eH[bp],ax + xor ax,ax + div bx + mov word ptr -10H[bp],ax + mov bx,word ptr 12H[bp] + mov ax,word ptr 10H[bp] + mov cx,word ptr 0aH[bp] + mov dx,word ptr 8[bp] + call near ptr MX_TEXT:SUBCLIPBOX + jae L$2 + jmp near ptr L$7 +L$2: + mov word ptr 0aH[bp],cx + mov word ptr 8[bp],dx + sub word ptr 12H[bp],bx + sub word ptr 10H[bp],ax + mul word ptr cs:MX_BYTESPERLINE + mov di,bx + shr di,1 + shr di,1 + add di,ax + mov word ptr -2[bp],di + mov es,word ptr cs:MX_VIDEOSEGMENT + and bl,3 + mov byte ptr -6[bp],bl + mov cl,bl + mov al,11H + shl al,cl + mov byte ptr -14H[bp],al + mov ax,word ptr 10H[bp] + test ax,ax + je L$3 + mov bx,ax + mul word ptr -10H[bp] + mov cx,dx + mov ax,bx + mul word ptr -0eH[bp] + add ax,cx + mul word ptr 0eH[bp] + add word ptr 14H[bp],ax +L$3: + mov ax,word ptr 12H[bp] + test ax,ax + je L$4 + mov bx,ax + mul word ptr -0cH[bp] + mov cx,dx + mov ax,bx + mul word ptr -0aH[bp] + add ax,cx + add word ptr 14H[bp],ax +L$4: + mov ax,word ptr -0eH[bp] + mul word ptr 0eH[bp] + mov word ptr -0eH[bp],ax + mov bx,word ptr 6[bp] + mov byte ptr -8[bp],bh + xor bh,bh + cmp bl,5 + jbe L$5 + xor bl,bl +L$5: + shl bx,1 + mov ax,word ptr cs:L$1[bx] + mov word ptr -4[bp],ax + mov ds,word ptr 16H[bp] + xor ax,ax + mov word ptr -12H[bp],ax +L$6: + mov si,word ptr 14H[bp] + mov ah,byte ptr -14H[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov ah,byte ptr -6[bp] + and ah,3 + mov al,4 + mov dx,3ceH + out dx,ax + mov cx,word ptr 8[bp] + mov di,word ptr -2[bp] + mov ah,byte ptr -8[bp] + xor bx,bx + mov dx,word ptr cs:MX_BYTESPERLINE + call word ptr -4[bp] + inc byte ptr -6[bp] + rol byte ptr -14H[bp],1 + adc word ptr -2[bp],0 + mov dx,word ptr -0cH[bp] + mov ax,word ptr -0aH[bp] + add word ptr -12H[bp],dx + adc word ptr 14H[bp],ax + dec word ptr 0aH[bp] + jne L$6 +L$7: + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 12H +L$8: + mov al,byte ptr [si] + mov byte ptr es:[di],al + add di,dx + dec cx + je L$9 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$8 + add si,word ptr 0eH[bp] + jmp L$8 +L$9: + ret +L$10: + mov al,byte ptr [si] + and byte ptr es:[di],al + add di,dx + dec cx + je L$11 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$10 + add si,word ptr 0eH[bp] + jmp L$10 +L$11: + ret +L$12: + mov al,byte ptr [si] + or byte ptr es:[di],al + add di,dx + dec cx + je L$13 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$12 + add si,word ptr 0eH[bp] + jmp L$12 +L$13: + ret +L$14: + mov al,byte ptr [si] + xor byte ptr es:[di],al + add di,dx + dec cx + je L$15 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$14 + add si,word ptr 0eH[bp] + jmp L$14 +L$15: + ret +L$16: + mov al,byte ptr [si] + cmp al,ah + je L$17 + mov byte ptr es:[di],al +L$17: + add di,dx + dec cx + je L$18 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$16 + add si,word ptr 0eH[bp] + jmp L$16 +L$18: + ret +L$19: + mov al,byte ptr [si] + add byte ptr es:[di],al + add di,dx + dec cx + je L$20 + add si,word ptr -0eH[bp] + add bx,word ptr -10H[bp] + jae L$19 + add si,word ptr 0eH[bp] + jmp L$19 +L$20: + ret +MX_TEXT ENDS + END diff --git a/16/xw__/mxsl.asm b/16/xw__/mxsl.asm new file mode 100755 index 00000000..2b25844a --- /dev/null +++ b/16/xw__/mxsl.asm @@ -0,0 +1,37 @@ +.387 + PUBLIC MXSTARTLINE + EXTRN MX_BYTESPERLINE:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSTARTLINE: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + mul word ptr cs:MX_BYTESPERLINE + xchg ax,bx + mov dx,3daH +L$1: + in al,dx + test al,8 + jne L$1 + mov dx,3d4H + mov al,0cH + mov ah,bh + cli + out dx,ax + mov al,0dH + mov ah,bl + out dx,ax + sti + mov dx,3daH +L$2: + in al,dx + test al,8 + je L$2 + xor ax,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxsm.asm b/16/xw__/mxsm.asm new file mode 100755 index 00000000..ccad79ec --- /dev/null +++ b/16/xw__/mxsm.asm @@ -0,0 +1,450 @@ +.387 + PUBLIC MX_SCREENWIDTH + PUBLIC MX_SCREENHEIGHT + PUBLIC MX_BYTESPERLINE + PUBLIC MXSETMODE + PUBLIC MXCHANGEMODE + PUBLIC MXGETASPECT + PUBLIC MXGETSCREENSIZE + EXTRN MX_CODESEGMENT:BYTE + EXTRN MXSETSYSCLIPREGION:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MX_SCREENWIDTH: + add byte ptr [bx+si],al +MX_SCREENHEIGHT: + add byte ptr [bx+si],al +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +MX_BYTESPERLINE: + add byte ptr [bx+si],al +L$3: + or word ptr 14H[bx+si],ax + add byte ptr [bx],dl + jcxz L$4 +L$4: + DB 0 +L$5: + or word ptr 14H[bx+di],ax + add byte ptr [bx],dl + jcxz L$6 +L$6: + DB 0 +L$7: + add byte ptr 1[bx],bl + dec di + add dl,byte ptr 3[bx+si] + add byte ptr [si],54H + add ax,1380H + sub byte ptr [bx+si],al + DB 0 +L$8: + add byte ptr 1[bp+di],ch + pop cx + add bl,byte ptr 3[bp+si] + mov es,word ptr [si] + pop si + add ax,138aH + sub ax,0 + push es + mov di,1f07H + adc byte ptr -7aefH[bp+di],al + adc bl,byte ptr 15H[di] + arpl word ptr ds:[0baH],dx + DB 0 +L$9: + push es + DD ds:[7bfH] + pushf + adc word ptr -70eeH[bp],cx + adc ax,1696H + mov cx,0 +L$10: + push es + or ax,3e07H + adc dl,ch + adc word ptr -20eeH[si],cx + adc ax,16e7H + push es + add byte ptr [bx+si],al +L$11: + add byte ptr 1[si],dh + arpl word ptr [bp+si],ax + add dx,word ptr fs:6804H[bx] + add ax,695H + xchg byte ptr [bx],al + lock or word ptr 0fH[bx+si],sp + xor word ptr [bx+si],dx + pop bx + adc word ptr 5712H[di],cx + adc si,word ptr [bp+si] + adc al,0 + adc ax,1660H + adc byte ptr [bx],0e3H + add byte ptr [bx+si],al +L$12: + arpl word ptr ds:[500H],ax + add byte ptr 1[bx+si],al + enter 1a00H,0 + DW offset L$9 + DW offset L$5 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$13: + jcxz L$14 + DB 0 +L$14: + add word ptr [bx+si],ax + inc ax + add ax,si + add byte ptr [bp+si],bl + add byte ptr [bp+si],bl + DW offset L$5 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$15: + arpl word ptr ds:[0a00H],ax + add byte ptr 1[bx+si],al + nop + add word ptr [bp+si],bx + add byte ptr [bp+si],cl + DW offset L$3 + add byte ptr [bx+si],al + xor ax,word ptr [bp+di] +L$16: + jcxz L$17 + DB 0 +L$17: + add al,byte ptr [bx+si] + inc ax + add ax,sp + DD L$18 +L$18: + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$19: + sbb ax,word ptr [eax] + adc al,0 + push 0c801H + add byte ptr [bp+si],ch + add byte ptr [bp+si],cl + DW offset L$5 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$20: + out 9,ax + add byte ptr [bx+si],cl + add byte ptr 1[bx+si],ch + lock add byte ptr [bp+si],ch + add byte ptr [bp+si],bl + DW offset L$5 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$21: + sbb ax,word ptr [eax] + sub byte ptr [bx+si],al + push 9001H + add word ptr [bp+si],bp + add byte ptr [bp+si],cl + DW offset L$3 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$22: + out 9,ax + add byte ptr [bx+si],dl + add byte ptr 1[bx+si],ch + loopnz L$23 + DW offset L$8 +L$23 equ $-1 + DW offset L$10 + DW offset L$3 + add byte ptr [bx+si],al + fadd dword ptr [bp+si] +L$24: + mov word ptr ds:[0],ax + add byte ptr [bx+si],al + inc ax + add word ptr 1a00H[bx],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],dl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$25: + mov word ptr 0,ax + add byte ptr [bx+si],al + inc ax + add word ptr 1a00H[bx],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add byte ptr [bp+di],dh + DB 3 +L$26: + cmpsw + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push 0e001H + add word ptr [bp+si],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],dl + add byte ptr [bx+si],al + add al,bl + DB 2 +L$27: + cmpsw + add byte ptr [bx+si],al + add byte ptr [bx+si],al + push 0e001H + add word ptr [bp+si],bp + add byte ptr [bp+si],bh + add byte ptr [bp+si],cl + add byte ptr [bx+si],al + add al,bl + DB 2 +L$28: + out 1,ax + add byte ptr [bp+si],al + add byte ptr 5801H[bx+si],dl + add ch,byte ptr [bp+si] + add byte ptr [bx+si],al + pop word ptr [bp+si] +L$29: + DW offset L$24 + DW offset L$12 + DW offset L$13 + DW offset L$25 + DW offset L$15 + DW offset L$16 + DW offset L$26 + DW offset L$19 + DW offset L$20 + DW offset L$27 + DW offset L$21 + DW offset L$22 + DW offset L$28 +L$30: + mov ax,3 + int 10H + mov word ptr MX_SCREENHEIGHT,0 + mov word ptr MX_BYTESPERLINE,0 + ret +MXSETMODE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ds,word ptr cs:MX_CODESEGMENT + mov si,word ptr 6[bp] + cmp si,0dH + jbe L$31 + jmp near ptr L$36 +L$31: + test si,si + jne L$32 + call near ptr L$30 + jmp near ptr L$36 +L$32: + dec si + shl si,1 + mov si,word ptr L$29[si] + cld + push si + mov ax,13H + int 10H + pop si + mov dx,3c4H + mov ax,604H + out dx,ax + mov ax,100H + out dx,ax + mov dx,3c2H + lodsb + out dx,al + mov dx,3c4H + mov ax,300H + out dx,ax + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + and al,7fH + out dx,al + lodsw + mov word ptr L$1,ax + lodsw + mov word ptr L$2,ax + lodsw + mov word ptr MX_SCREENWIDTH,ax + shr ax,1 + shr ax,1 + mov word ptr MX_BYTESPERLINE,ax + lodsw + mov word ptr MX_SCREENHEIGHT,ax + mov bx,si + mov dx,3d4H +L$33: + mov si,word ptr [bx] + inc bx + inc bx + test si,si + je L$35 +L$34: + lodsw + test ax,ax + je L$33 + out dx,ax + jmp L$34 +L$35: + push word ptr MX_SCREENWIDTH + push word ptr [bx] + push cs + call near ptr MX_TEXT:MXSETSYSCLIPREGION + mov dx,3c4H + mov ax,0f02H + out dx,ax + mov es,word ptr MX_TEXT:MX_VIDEOSEGMENT + xor di,di + mov cx,8000H + xor ax,ax + rep stosw + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + or al,80H + out dx,al +L$36: + xor ax,ax + mov ax,word ptr MX_SCREENWIDTH + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 2 +MXCHANGEMODE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ds,word ptr cs:MX_CODESEGMENT + mov si,word ptr 6[bp] + cmp si,0dH + ja L$40 + test si,si + je L$40 + dec si + shl si,1 + mov si,word ptr L$29[si] + cld + mov dx,3c4H + mov ax,604H + out dx,ax + mov ax,100H + out dx,ax + mov dx,3c2H + lodsb + out dx,al + mov dx,3c4H + mov ax,300H + out dx,ax + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + and al,7fH + out dx,al + lodsw + mov word ptr L$1,ax + lodsw + mov word ptr L$2,ax + lodsw + mov word ptr MX_SCREENWIDTH,ax + lodsw + mov word ptr MX_SCREENHEIGHT,ax + mov bx,si + mov dx,3d4H +L$37: + mov si,word ptr [bx] + inc bx + inc bx + test si,si + je L$39 +L$38: + lodsw + test ax,ax + je L$37 + cmp al,13H + je L$38 + out dx,ax + jmp L$38 +L$39: + mov dx,3d4H + mov al,11H + out dx,al + inc dx + in al,dx + or al,80H + out dx,al +L$40: + xor ax,ax + mov ax,word ptr MX_SCREENWIDTH + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 2 +MXGETASPECT: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov ax,word ptr cs:L$1 + mov word ptr [si],ax + lds si,dword ptr 6[bp] + mov ax,word ptr cs:L$2 + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MXGETSCREENSIZE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov ax,word ptr cs:MX_SCREENWIDTH + mov word ptr [si],ax + lds si,dword ptr 6[bp] + mov ax,word ptr cs:MX_SCREENHEIGHT + mov word ptr [si],ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxsp.asm b/16/xw__/mxsp.asm new file mode 100755 index 00000000..7ed046f6 --- /dev/null +++ b/16/xw__/mxsp.asm @@ -0,0 +1,34 @@ +.387 + PUBLIC MXSETPALETTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSETPALETTE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + lds si,dword ptr 0aH[bp] + mov cx,word ptr 6[bp] + mov ax,word ptr 8[bp] + mov dx,3c8H + out dx,al + inc dx + cld + cli +L$1: + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + loop L$1 + sti + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxss.asm b/16/xw__/mxss.asm new file mode 100755 index 00000000..aba7db99 --- /dev/null +++ b/16/xw__/mxss.asm @@ -0,0 +1,45 @@ +.387 + PUBLIC MXSPLITSCREEN +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXSPLITSCREEN: + push bp + mov bp,sp + sub sp,0 + mov ax,word ptr 6[bp] + shl ax,1 + mov bh,ah + mov bl,ah + and bx,201H + mov cl,4 + shl bx,cl + shl bh,1 + mov dx,3d4H + mov ah,al + mov al,18H + out dx,ax + mov al,7 + out dx,al + inc dx + in al,dx + dec dx + mov ah,al + and ah,0efH + or ah,bl + mov al,7 + out dx,ax + mov al,9 + out dx,al + inc dx + in al,dx + dec dx + mov ah,al + and ah,0bfH + or ah,bh + mov al,9 + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxtl.asm b/16/xw__/mxtl.asm new file mode 100755 index 00000000..e93aedf6 --- /dev/null +++ b/16/xw__/mxtl.asm @@ -0,0 +1,123 @@ +.387 + PUBLIC MXPUTTILE + PUBLIC MXTRANSPUTTILE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MX_VIDEOSEGMENT:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXPUTTILE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ax,word ptr 0aH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 0cH[bp] + shr di,1 + shr di,1 + add di,ax + mov es,word ptr cs:MX_VIDEOSEGMENT + lds si,dword ptr 0eH[bp] + shr word ptr 8[bp],1 + shr word ptr 8[bp],1 + mov cl,byte ptr 0cH[bp] + and cl,3 + mov ah,11H + shl ah,cl + mov word ptr 0aH[bp],4 + mov bx,word ptr cs:MX_BYTESPERLINE + sub bx,word ptr 8[bp] +L$1: + mov al,2 + mov dx,3c4H + out dx,ax + mov word ptr 0cH[bp],di + mov dx,word ptr 6[bp] +L$2: + mov cx,word ptr 8[bp] + shr cx,1 + rep movsw + rcl cx,1 + rep movsb + add di,bx + dec dx + jne L$2 + mov di,word ptr 0cH[bp] + rol ah,1 + adc di,0 + dec word ptr 0aH[bp] + jne L$1 + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MXTRANSPUTTILE: + push bp + mov bp,sp + sub sp,0 + push ds + push si + push es + push di + mov ax,word ptr 0aH[bp] + mul word ptr cs:MX_BYTESPERLINE + mov di,word ptr 0cH[bp] + shr di,1 + shr di,1 + add di,ax + mov es,word ptr cs:MX_VIDEOSEGMENT + lds si,dword ptr 0eH[bp] + shr word ptr 8[bp],1 + shr word ptr 8[bp],1 + mov cl,byte ptr 0cH[bp] + and cl,3 + mov ah,11H + shl ah,cl + mov word ptr 0aH[bp],4 + mov bx,word ptr cs:MX_BYTESPERLINE + sub bx,word ptr 8[bp] +L$3: + mov al,2 + mov dx,3c4H + out dx,ax + mov word ptr 0cH[bp],di + mov dx,word ptr 6[bp] +L$4: + mov cx,word ptr 8[bp] + jcxz L$7 +L$5: + mov al,byte ptr [si] + test al,al + je L$6 + mov byte ptr es:[di],al +L$6: + inc si + inc di + dec cx + jne L$5 +L$7: + add di,bx + dec dx + jne L$4 + mov di,word ptr 0cH[bp] + rol ah,1 + adc di,0 + dec word ptr 0aH[bp] + jne L$3 + xor ax,ax + pop di + pop es + pop si + pop ds + mov sp,bp + pop bp + retf 0cH +MX_TEXT ENDS + END diff --git a/16/xw__/mxvs.asm b/16/xw__/mxvs.asm new file mode 100755 index 00000000..feafb66a --- /dev/null +++ b/16/xw__/mxvs.asm @@ -0,0 +1,69 @@ +.387 + PUBLIC MXSETVIRTUALSCREEN + PUBLIC MXGETVIRTUALSCREEN + EXTRN MX_CODESEGMENT:BYTE + EXTRN MX_BYTESPERLINE:BYTE + EXTRN MXROWADDRESS:BYTE + EXTRN MXSETSYSCLIPREGION:BYTE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +L$1: + add byte ptr [bx+si],al +L$2: + add byte ptr [bx+si],al +MXSETVIRTUALSCREEN: + push bp + mov bp,sp + sub sp,0 + push ds + mov ds,word ptr cs:MX_CODESEGMENT + mov ax,1 + cmp word ptr 8[bp],140H + jb L$3 + push ax + mov dx,4 + xor ax,ax + div word ptr 8[bp] + cmp word ptr 6[bp],ax + pop ax + ja L$3 + mov ax,word ptr 8[bp] + and ax,0fff8H + mov word ptr L$1,ax + shr ax,1 + shr ax,1 + mov word ptr MX_TEXT:MX_BYTESPERLINE,ax + shr ax,1 + push ax + call far ptr MXROWADDRESS + mov ax,word ptr 6[bp] + mov word ptr L$2,ax + push word ptr 8[bp] + push word ptr 6[bp] + call far ptr MXSETSYSCLIPREGION + xor ax,ax +L$3: + pop ds + mov sp,bp + pop bp + retf 4 +MXGETVIRTUALSCREEN: + push bp + mov bp,sp + sub sp,0 + push ds + push si + mov ax,word ptr cs:L$1 + lds si,dword ptr 0aH[bp] + mov word ptr [si],ax + mov ax,word ptr cs:L$2 + lds si,dword ptr 6[bp] + mov word ptr [si],ax + xor ax,ax + pop si + pop ds + mov sp,bp + pop bp + retf 8 +MX_TEXT ENDS + END diff --git a/16/xw__/mxwd.asm b/16/xw__/mxwd.asm new file mode 100755 index 00000000..7f491f39 --- /dev/null +++ b/16/xw__/mxwd.asm @@ -0,0 +1,13 @@ +.387 + PUBLIC MXWAITDISPLAY +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWAITDISPLAY: + mov dx,3daH +L$1: + in al,dx + test al,8 + jne L$1 + retf +MX_TEXT ENDS + END diff --git a/16/xw__/mxwm.asm b/16/xw__/mxwm.asm new file mode 100755 index 00000000..271eebad --- /dev/null +++ b/16/xw__/mxwm.asm @@ -0,0 +1,19 @@ +.387 + PUBLIC MXWRITEMODE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWRITEMODE: + push bp + mov bp,sp + sub sp,0 + mov dx,3ceH + mov ah,byte ptr 6[bp] + and ah,3 + or ah,40H + mov al,5 + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxwp.asm b/16/xw__/mxwp.asm new file mode 100755 index 00000000..45e32f37 --- /dev/null +++ b/16/xw__/mxwp.asm @@ -0,0 +1,31 @@ +.387 + PUBLIC MXWRITEPLANE + PUBLIC MXREADPLANE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWRITEPLANE: + push bp + mov bp,sp + sub sp,0 + mov ah,byte ptr 6[bp] + and ah,0fH + mov al,2 + mov dx,3c4H + out dx,ax + mov sp,bp + pop bp + retf 2 +MXREADPLANE: + push bp + mov bp,sp + sub sp,0 + mov al,4 + mov ah,byte ptr 6[bp] + and ah,3 + mov dx,3ceH + out dx,ax + mov sp,bp + pop bp + retf 2 +MX_TEXT ENDS + END diff --git a/16/xw__/mxwr.asm b/16/xw__/mxwr.asm new file mode 100755 index 00000000..5fccb47d --- /dev/null +++ b/16/xw__/mxwr.asm @@ -0,0 +1,13 @@ +.387 + PUBLIC MXWAITRETRACE +MX_TEXT SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP +MXWAITRETRACE: + mov dx,3daH +L$1: + in al,dx + test al,8 + je L$1 + retf +MX_TEXT ENDS + END diff --git a/16/xw__/readme.txt b/16/xw__/readme.txt new file mode 100755 index 00000000..306e8b9a --- /dev/null +++ b/16/xw__/readme.txt @@ -0,0 +1,8 @@ +ModeX - A graphical library for DOS programs +Copyright (c) 1993-1994 Alessandro Scotti +http://www.ascotti.org/ + +Please look at the above site in the "Art of..." and +then in the "Old programs" section for more information. + + diff --git a/16/xw__/xw.bat b/16/xw__/xw.bat new file mode 100755 index 00000000..1fd24399 --- /dev/null +++ b/16/xw__/xw.bat @@ -0,0 +1,39 @@ +@echo off +wdis -a MXBB.OBJ > mxbb.asm +wdis -a MXCC.OBJ > mxcc.asm +wdis -a MXCG.OBJ > mxcg.asm +wdis -a MXCL.OBJ > mxcl.asm +wdis -a MXCR.OBJ > mxcl.asm +wdis -a MXFB.OBJ > mxfb.asm +wdis -a MXFP.OBJ > mxfp.asm +wdis -a MXGC.OBJ > mxgc.asm +wdis -a MXGI.OBJ > mxgi.asm +wdis -a MXGM.OBJ > mxgm.asm +wdis -a MXGP.OBJ > mxgp.asm +wdis -a MXGV.OBJ > mxgv.asm +wdis -a MXHL.OBJ > mxhl.asm +wdis -a MXIT.OBJ > mxit.asm +wdis -a MXLL.OBJ > mxll.asm +wdis -a MXLN.OBJ > mxln.asm +wdis -a MXOT.OBJ > mxot.asm +wdis -a MXPB.OBJ > mxpb.asm +wdis -a MXPF.OBJ > mxpf.asm +wdis -a MXPG.OBJ > mxpg.asm +wdis -a MXPI.OBJ > mxpi.asm +wdis -a MXPN.OBJ > mxpn.asm +wdis -a MXPP.OBJ > mxpp.asm +wdis -a MXRA.OBJ > mxra.asm +wdis -a MXRP.OBJ > mxrp.asm +wdis -a MXSA.OBJ > mxsa.asm +wdis -a MXSC.OBJ > mxsc.asm +wdis -a MXSI.OBJ > mxsi.asm +wdis -a MXSL.OBJ > mxsl.asm +wdis -a MXSM.OBJ > mxsm.asm +wdis -a MXSP.OBJ > mxsp.asm +wdis -a MXSS.OBJ > mxss.asm +wdis -a MXTL.OBJ > mxtl.asm +wdis -a MXVS.OBJ > mxvs.asm +wdis -a MXWD.OBJ > mxwd.asm +wdis -a MXWM.OBJ > mxwm.asm +wdis -a MXWP.OBJ > mxwp.asm +wdis -a MXWR.OBJ > mxwr.asm diff --git a/awoo.sh b/awoo.sh index 5073f2bf..f5b766ec 100755 --- a/awoo.sh +++ b/awoo.sh @@ -1,6 +1,12 @@ #!/bin/bash +if [ -z "$*" ]; then + pee="wwww" + else + pee="$*" +fi +##echo "$pee" git add . -. ./boop.sh "$*" +. ./boop.sh "$pee" cp -fp *.exe /var/www/ scp -rp -P 26 *.exe 4ch.mooo.com:/var/www/16/ #if [ -f "*.exe" ] diff --git a/bakapi.exe b/bakapi.exe index 12a74bea..fee866d4 100755 Binary files a/bakapi.exe and b/bakapi.exe differ diff --git a/exmmtest.exe b/exmmtest.exe index 2e41b423..beb8f6e2 100755 Binary files a/exmmtest.exe and b/exmmtest.exe differ diff --git a/fmemtest.exe b/fmemtest.exe index c88212ab..f7f7ff4d 100755 Binary files a/fmemtest.exe and b/fmemtest.exe differ diff --git a/fontgfx.exe b/fontgfx.exe index 577a02f4..ed49d78a 100755 Binary files a/fontgfx.exe and b/fontgfx.exe differ diff --git a/fonttest.exe b/fonttest.exe index c59b86a5..882c4d8f 100755 Binary files a/fonttest.exe and b/fonttest.exe differ diff --git a/inputest.exe b/inputest.exe index 09cb3893..ed7e43c8 100755 Binary files a/inputest.exe and b/inputest.exe differ diff --git a/makefile b/makefile index 6c388c71..723216e7 100755 --- a/makefile +++ b/makefile @@ -22,6 +22,10 @@ # -0 8088/8086 class code generation # -s disable stack overflow checking +# -zk0u translate kanji to unicode... wwww +# -zk0 kanji support~ +# -zkl current codepage + #%.C #192x144 #wwww will add these @@ -42,9 +46,6 @@ OBJ=obj #!endif TARGET_OS = dos -#-zk0u = translate kanji to unicode... wwww -#-zk0 = kanji support~ -#-zkl = current codepage #EXMMTESTDIR=16$(DIRSEP)exmmtest$(DIRSEP) SRC=src$(DIRSEP) @@ -53,19 +54,22 @@ JSMNLIB=$(SRCLIB)jsmn$(DIRSEP) NYANLIB=$(SRCLIB)nyan$(DIRSEP) #EXMMLIB=$(SRCLIB)exmm$(DIRSEP) MODEXLIB=$(SRCLIB)modex16$(DIRSEP) +MODEXLIB_=$(SRCLIB)modex$(DIRSEP) VGMSNDLIB=$(SRCLIB)vgmsnd$(DIRSEP) DOSLIB=$(SRCLIB)doslib$(DIRSEP) WCPULIB=$(SRCLIB)wcpu$(DIRSEP) +AFLAGS=-mh -0 -d1 16FLAGS=-fh=16.hed BAKAPIFLAGS=-fh=bakapi.hed SFLAGS=-sg -st -of+ -zu -zdf -zff -zgf -k55808#60000#32768 DFLAGS=-DTARGET_MSDOS=16 -DMSDOS=1 $(SFLAGS) ZFLAGS=-zk0 -zq -zc -zp8# -zm -CFLAGS=$(IFLAGS) -mh -lr -l=dos -wo# -d2##wwww -OFLAGS=-obmiler -out -oh -ei -zp8 -0 -fpi87 -onac -ol+ -ok####x +CFLAGS=$(AFLAGS) $(IFLAGS)-lr -l=dos -wo##wwww +OFLAGS=-obmiler -out -oh -ei -zp8 -fpi87 -onac -ol+ -ok####x FLAGS=$(CFLAGS) $(OFLAGS) $(DFLAGS) $(ZFLAGS) + DOSLIBEXMMOBJ = himemsys.$(OBJ) emm.$(OBJ) VGMSNDOBJ = vgmSnd.$(OBJ) 16_snd.$(OBJ) DOSLIBOBJ = adlib.$(OBJ) 8254.$(OBJ) 8259.$(OBJ) dos.$(OBJ) cpu.$(OBJ) @@ -87,8 +91,8 @@ all: $(EXEC) comp 16.exe: 16.$(OBJ) mapread.$(OBJ) jsmn.$(OBJ) $(16LIBOBJS) gfx.lib wcl $(FLAGS) $(16FLAGS) 16.$(OBJ) mapread.$(OBJ) jsmn.$(OBJ) $(16LIBOBJS) gfx.lib -fm=16.map -bakapi.exe: bakapi.$(OBJ) $(16LIBOBJS) gfx.lib - wcl $(FLAGS) $(BAKAPIFLAGS) bakapi.$(OBJ) $(16LIBOBJS) gfx.lib -fm=bakapi.map +bakapi.exe: bakapi.$(OBJ) $(16LIBOBJS) gfx.lib modex.lib + wcl $(FLAGS) $(BAKAPIFLAGS) bakapi.$(OBJ) $(16LIBOBJS) gfx.lib modex.lib -fm=bakapi.map # #Test Executables! # @@ -372,13 +376,21 @@ vgmSnd.$(OBJ): $(VGMSNDLIB)vgmSnd.h $(VGMSNDLIB)vgmSnd.c #memory.$(OBJ): $(EXMMLIB)memory.h $(EXMMLIB)memory.c # wcl $(FLAGS) $(MFLAGS) -c $(EXMMLIB)memory.c +c_utils.$(OBJ): $(MODEXLIB_)c_utils.asm + wcl -c $(AFLAGS) $(MODEXLIB_)c_utils.asm +modex.$(OBJ): $(MODEXLIB_)modex.asm + wcl -c $(AFLAGS) $(MODEXLIB_)modex.asm + # #other~ # clean: .symbolic @$(REMOVECOMMAND) $(EXEC) @$(REMOVECOMMAND) *.$(OBJ) - @$(REMOVECOMMAND) *.lib + @$(REMOVECOMMAND) 16.lib + @$(REMOVECOMMAND) gfx.lib + @$(REMOVECOMMAND) doslib.lib + @$(REMOVECOMMAND) vgmsnd.lib @wlib -n 16.lib @wlib -n gfx.lib @wlib -n doslib.lib @@ -411,8 +423,27 @@ clean: .symbolic comp: .symbolic @upx -9 -qqq $(EXEC) + @upx -9 -qqq x-demo.exe updatelibs: .symbolic - cd $(JSMNLIB) - git pull - cd ../../../ + @cd $(JSMNLIB) + @git pull + @cd ../../../ + +xlib: .symbolic + @cd 16/xlib + @wmake clean + @wmake all + @cd ../../ + +mx: .symbolic + @cd 16/xw +# @wmake clean + @wmake all + @cd ../../ + +mx_: .symbolic + @cd 16/xw_ + @wmake -f makefile all + @cd ../../ + diff --git a/maptest.exe b/maptest.exe index 648302a2..34a080b3 100755 Binary files a/maptest.exe and b/maptest.exe differ diff --git a/palettec.exe b/palettec.exe index a357fa6f..42f7a095 100755 Binary files a/palettec.exe and b/palettec.exe differ diff --git a/palettel.exe b/palettel.exe index 1ced8d49..bd3308a9 100755 Binary files a/palettel.exe and b/palettel.exe differ diff --git a/pcxtest.exe b/pcxtest.exe index bfbd9f63..e9ccd81f 100755 Binary files a/pcxtest.exe and b/pcxtest.exe differ diff --git a/pcxtest2.exe b/pcxtest2.exe index e77b8140..ea2e98bb 100755 Binary files a/pcxtest2.exe and b/pcxtest2.exe differ diff --git a/planrpcx.exe b/planrpcx.exe index 89919c98..2a242c93 100755 Binary files a/planrpcx.exe and b/planrpcx.exe differ diff --git a/scroll.exe b/scroll.exe index 8b04afe2..ee058e28 100755 Binary files a/scroll.exe and b/scroll.exe differ diff --git a/sparky4.do b/sparky4.do index e9602c62..8c5dc821 100755 --- a/sparky4.do +++ b/sparky4.do @@ -5,7 +5,15 @@ code it! what? -planar function from pcx must be made~ + + +test which modex library is faster! +edit input and switch unecessary words to bytes + + + + +planar function from pcx must be made~ ok font! ok jis! ... diff --git a/src/bakapi.c b/src/bakapi.c index 5022f0da..16a0c77f 100755 --- a/src/bakapi.c +++ b/src/bakapi.c @@ -41,7 +41,11 @@ main(int argc, char *argvar[]) xdir=1; ydir=1; +#ifdef MXLIB VGAmodeX(1, &gvar); +#else + mxSetMode(3); +#endif bakapee.xx = rand()&0%gvar.video.page[0].width; bakapee.yy = rand()&0%gvar.video.page[0].height; bakapee.gq = 0; @@ -73,9 +77,14 @@ main(int argc, char *argvar[]) } else { + #ifndef MXLIB + mxChangeMode(0); +#else VGAmodeX(0, &gvar); +#endif //modexLeave(); // user imput switch + fprintf(stderr, "xx=%d yy=%d\n", bakapee.xx, bakapee.yy); printf("Enter 1, 2, 3, 4, or 6 to run a screensaver, or enter 0 to quit.\n", getch()); // prompt the user scanf("%d", &key); //if(key==3){xx=yy=0;} // crazy screen saver wwww @@ -83,7 +92,11 @@ main(int argc, char *argvar[]) gvar.video.page[0] = modexDefaultPage(&gvar.video.page[0]); gvar.video.page[0].width += (TILEWH*2); gvar.video.page[0].height += (TILEWH*2); +#ifdef MXLIB VGAmodeX(1, &gvar); +#else + mxChangeMode(3); +#endif modexShowPage(&gvar.video.page[0]); } } diff --git a/src/lib/16_in.c b/src/lib/16_in.c index bb11c095..84804f6c 100755 --- a/src/lib/16_in.c +++ b/src/lib/16_in.c @@ -849,17 +849,18 @@ register KeyboardDef *def; mx = motion_Left,my = motion_Down; else if (Keyboard[def->downright]) mx = motion_Right,my = motion_Down;*/ - //if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){ + if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down] && player[playnum].d == 2))// || player[playnum].info.dir == 0) my = motion_Up; if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up] && player[playnum].d == 2))// || player[playnum].info.dir == 4) my = motion_Down; - //}else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){ + }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){ if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right] && player[playnum].d == 2))// || player[playnum].info.dir == 1) mx = motion_Left; if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left] && player[playnum].d == 2))// || player[playnum].info.dir == 3) mx = motion_Right; - //} + } + //input from player if (inpu.Keyboard[def->button0]) buttons += 1 << 0; if (inpu.Keyboard[def->button1]) diff --git a/src/lib/bakapee.c b/src/lib/bakapee.c index 040db6f9..000ac84a 100755 --- a/src/lib/bakapee.c +++ b/src/lib/bakapee.c @@ -63,11 +63,16 @@ void ssd(page_t *page, bakapee_t *pee, word svq) }else pee->sy = 0; } -//plot pixel +//plot pixel or plot tile void dingpp(page_t *page, bakapee_t *pee) { #ifdef TILE +#ifndef MXLIB + //fill_block(pee->xx, pee->yy, pee->xx+TILEWH, pee->yy+TILEWH, pee->coor); + mxFillBox(pee->xx, pee->yy, TILEWH, TILEWH, pee->coor, OP_SET); +#else modexClearRegion(page, pee->xx, pee->yy, TILEWH, TILEWH, pee->coor); +#endif #else modexputPixel(page, pee->xx, pee->yy, pee->coor); #endif diff --git a/src/lib/bakapee.h b/src/lib/bakapee.h index 3e228a4a..df74c1bd 100755 --- a/src/lib/bakapee.h +++ b/src/lib/bakapee.h @@ -25,6 +25,8 @@ #include "src/lib/16_head.h" #include "src/lib/modex16.h" +//#include "src/lib/modex/modex.h" +#include "16/x/modex.h" #define TILEWH 16 #define QUADWH TILEWH/2 @@ -32,7 +34,10 @@ #define LGQ 32 #define HGQ 55 -//#define TILE +#define TILE + +//which lib? +#define MXLIB typedef struct { word gq; diff --git a/src/lib/modex/asm.bat b/src/lib/modex/asm.bat new file mode 100755 index 00000000..2e5785f9 --- /dev/null +++ b/src/lib/modex/asm.bat @@ -0,0 +1 @@ +MASM modex,modex,modex,nul \ No newline at end of file diff --git a/src/lib/modex/c_utils.asm b/src/lib/modex/c_utils.asm new file mode 100755 index 00000000..01182013 --- /dev/null +++ b/src/lib/modex/c_utils.asm @@ -0,0 +1,456 @@ +;======================================================= +;=== C_UTILS.ASM - Asm Utilities for C/C++ === +;======================================================= + + PAGE 255, 132 + + .MODEL Huge +; .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +; PUSHx MACRO R1, R2, R3, R4;, R5, R6, R7, R8 +; IFNB +; push R1 ; Save R1 +; PUSHx R2, R3, R4;, R5, R6, R7, R8 +; ENDIF +; ENDM +; +; POPx MACRO R1, R2, R3, R4;, R5, R6, R7, R8 +; IFNB +; pop R1 ; Restore R1 +; POPx R2, R3, R4;, R5, R6, R7, R8 +; ENDIF +; ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + ?x2 EQU + ?x1 EQU + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;=========================================== +;void far pascal dos_print (far char *Text) +;=========================================== +; +; - Print Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DD ? ; Far Address of Text to print +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DP_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DP_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DP_Scan_it ; check again... + +@@DP_Got_len: + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 4 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;=========================================== +;void far pascal dos_prints (char far *Text) +;=========================================== +; +; Print Text Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DPS_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DPS_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DPS_Scan_it ; check again... + +@@DPS_Got_len: + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;========================================= +;void far pascal set_video_mode (int Mode) +;========================================= +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;=================================== +;int far pascal scan_keyboard (void) +;=================================== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + + mov AH, 01H ; Function #1 + INT 16H ; Call Keyboard Driver + JZ @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + INT 16H ; Get Keycode in AX + + OR AL, AL ; Low Byte Set (Ascii?) + JZ @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + JMP s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;======================================== +;int far pascal random_int (int MaxValue) +;======================================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;================================== +;void far pascal init_random (void) +;================================== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + +;========================================= +;int far pascal int_sqr (int X, int Round) +;========================================= +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + ;PUSHx BP, DI ; Save BP + push bp + push di + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + + ;POPx DI, BP ; Restore Registers + pop di + pop bp + ret 4 ; Exit + +INT_SQR ENDP + +;================================= +;int far pascal timer_count (void) +;================================= +; +; Returns the current timer value as an integer/long integer +; + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Clean Up Stack + +TIMER_COUNT ENDP + + + END diff --git a/src/lib/modex/c_utils.h b/src/lib/modex/c_utils.h new file mode 100755 index 00000000..9be6ba2d --- /dev/null +++ b/src/lib/modex/c_utils.h @@ -0,0 +1,117 @@ + +#ifndef __C_UTILS_H +#define __C_UTILS_H + + + /* Misc Constants */ + +#define True -1 +#define False 0 +#define nil 0 + + /* Color Constants */ + +#define c_BLACK 0 +#define c_BLUE 1 +#define c_GREEN 2 +#define c_CYAN 3 +#define c_RED 4 +#define c_PURPLE 5 +#define c_BROWN 6 +#define c_WHITE 7 +#define c_GREY 8 +#define c_bBLUE 9 +#define c_bGREEN 10 +#define c_bCYAN 11 +#define c_bRED 12 +#define c_bPURPLE 13 +#define c_YELLOW 14 +#define c_bWHITE 15 +#define c_BRIGHT 16 + + +#define Ky_F1 0x3B00 +#define Ky_F2 0x3C00 +#define Ky_F3 0x3D00 +#define Ky_F4 0x3E00 +#define Ky_F5 0x3F00 +#define Ky_F6 0x4000 +#define Ky_F7 0x4100 +#define Ky_F8 0x4200 +#define Ky_F9 0x4300 +#define Ky_F10 0x4400 + +#define Ky_Up 0x4800 +#define Ky_Left 0x4B00 +#define Ky_Right 0x4D00 +#define Ky_Down 0x5000 +#define Ky_SUp 0xC800 +#define Ky_SLeft 0xCB00 +#define Ky_SRight 0xCD00 +#define Ky_SDown 0xD000 + +#define Ky_Home 0x4700 +#define Ky_End 0x4F00 +#define Ky_PgUp 0x4900 +#define Ky_PgDn 0x5100 +#define Ky_SHome 0xC700 +#define Ky_SEnd 0xCF00 +#define Ky_SPgUp 0xC900 +#define Ky_SPgDn 0xD100 + +#define Ky_Ins 0x5200 +#define Ky_Del 0x5300 +#define Ky_SIns 0xC200 +#define Ky_SDel 0xC300 + +#define Ky_Tab 0x0009 +#define Ky_RvsTab 0x8F00 +#define Ky_STab 0x8F00 + +#define Ky_BS 0x0008 +#define Ky_CR 0x000D +#define Ky_ESC 0x001B +#define Ky_Clr 0x007F + +#define Ky_Plus 0x002D +#define Ky_Minus 0x002B + +#define Ky_AltA 0x1E00 +#define Ky_AltB 0x3000 +#define Ky_AltC 0x2E00 +#define Ky_AltD 0x2000 +#define Ky_AltE 0x1200 +#define Ky_AltF 0x2100 +#define Ky_AltG 0x2200 +#define Ky_AltH 0x2300 +#define Ky_AltI 0x1700 +#define Ky_AltJ 0x2400 +#define Ky_AltK 0x2500 +#define Ky_AltL 0x2600 +#define Ky_AltM 0x3200 +#define Ky_AltN 0x3100 +#define Ky_AltO 0x1800 +#define Ky_AltP 0x1900 +#define Ky_AltQ 0x1000 +#define Ky_AltR 0x1300 +#define Ky_AltS 0x1F00 +#define Ky_AltT 0x1400 +#define Ky_AltU 0x1600 +#define Ky_AltV 0x2F00 +#define Ky_AltW 0x1100 +#define Ky_AltX 0x2D00 +#define Ky_AltY 0x1500 +#define Ky_AltZ 0x2C00 + + /* .ASM Functions From C_UTILS.ASM */ + +void far pascal dos_print (char far *Text); +void far pascal dos_prints (char far *Text); +void far pascal set_video_mode (int Mode); +int far pascal scan_keyboard (void); +int far pascal random_int (int MaxValue); +void far pascal init_random (void); +int far pascal int_sqr (int X, int Round); +int far pascal timer_count (void); + +#endif diff --git a/src/lib/modex/c_utils.lst b/src/lib/modex/c_utils.lst new file mode 100755 index 00000000..f9664ba0 --- /dev/null +++ b/src/lib/modex/c_utils.lst @@ -0,0 +1,597 @@ +Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Page 1 - 1 + + + ;======================================================= + ;=== C_UTILS.ASM - Asm Utilities for C/C++ === + ;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + + PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + ; Macro to Clear a Register to 0 + + CLR MACRO Register + xor Register, Register ; Set Register = 0 + ENDM + + ; Macros to Decrement Counter & Jump on Condition + + LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 + ENDM + + LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 + ENDM + + + ; ==== General Constants ==== + + = 0000 False EQU 0 + =-0001 True EQU -1 + = 0000 nil EQU 0 + + = BYTE PTR b EQU BYTE PTR + = WORD PTR w EQU WORD PTR + = DWORD PTR d EQU DWORD PTR + = OFFSET o EQU OFFSET + = FAR PTR f EQU FAR PTR + = SHORT s EQU SHORT + = ?,?,?,? ?x4 EQU + = ?,?,? ?x3 EQU + + + 0000 .Data + + EVEN + + 0000 1CE5 7307 0322 RND_Seed DW 7397, 29447, 802 + 0006 00B3 00B7 00B6 RND_Mult DW 179, 183, 182 + 000C 8003 800B 800F RND_ModV DW 32771, 32779, 32783 + + 0012 0D 0A CR_LF DB 13, 10 ; the CRLF data + + 0000 .Code + + ;=========================================== + ;void far pascal dos_print (far char *Text) + ;=========================================== + ; + ; - Print Text Directly to DOS console w/ CR/LF + ; + + PUBLIC DOS_PRINT + + 0010 DP_Stack STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 00000000 DP_Text DD ? ; Far Address of Text to print + DP_Stack ENDS + + + 0000 DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0000 55 1 push BP ; Save R1 + 0001 1E 2 push DS ; Save R1 + 0002 56 3 push SI ; Save R1 + 0003 57 4 push DI ; Save R1 + 0004 8B EC mov BP, SP ; Set up Stack Frame + + 0006 C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + 0009 33 C9 1 xor CX, CX ; Set Register = 0 + 000B 8B F2 mov SI, DX ; DS:SI = String data + + 000D @@DP_Scan_it: + + 000D 80 3C 00 cmp b [SI], 0 ; Null Byte found? + 0010 74 04 je @@DP_Got_Len ; exit loop if so + + 0012 41 inc CX ; Len++ + 0013 46 inc SI ; Point to next char + 0014 EB F7 jmp s @@DP_Scan_it ; check again... + + 0016 @@DP_Got_len: + + 0016 E3 07 jcxz @No_Print ; Don't Print if empty + + 0018 BB 0001 mov BX, 1 ; 1= DOS Handle for Display + 001B B4 40 mov AH, 40h ; Write Text Function + 001D CD 21 int 21h ; Call DOS to do it + + 001F @No_Print: + 001F B8 ---- R mov AX, SEG DGROUP ; Restore DGroup + 0022 8E D8 mov DS, AX + + 0024 BA 0012 R mov DX, o CR_LF ; Get Addr of CR/LF pair + 0027 B9 0002 mov CX, 2 ; 2 Characters to Write + 002A BB 0001 mov BX, 1 ; 1= DOS Handle for Display + + 002D B4 40 mov AH, 40h ; Write Text Function + 002F CD 21 int 21h ; Call DOS to do it + + 0031 FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 0032 5F 1 pop DI ; Restore R1 + 0033 5E 2 pop SI ; Restore R1 + 0034 1F 3 pop DS ; Restore R1 + 0035 5D 4 pop BP ; Restore R1 + 0036 CA 0004 ret 4 ; Exit & Clean Up Stack + + 0039 DOS_PRINT ENDP + + + ;=========================================== + ;void far pascal dos_prints (char far *Text) + ;=========================================== + ; + ; Print Text Directly to DOS console + ; without a trailing CR/LF + ; + + PUBLIC DOS_PRINTS + + 0039 DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0039 55 1 push BP ; Save R1 + 003A 1E 2 push DS ; Save R1 + 003B 56 3 push SI ; Save R1 + 003C 57 4 push DI ; Save R1 + 003D 8B EC mov BP, SP ; Set up Stack Frame + + 003F C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + 0042 33 C9 1 xor CX, CX ; Set Register = 0 + 0044 8B F2 mov SI, DX ; DS:SI = String data + + 0046 @@DPS_Scan_it: + + 0046 80 3C 00 cmp b [SI], 0 ; Null Byte found? + 0049 74 04 je @@DPS_Got_Len ; exit loop if so + + 004B 41 inc CX ; Len++ + 004C 46 inc SI ; Point to next char + 004D EB F7 jmp s @@DPS_Scan_it ; check again... + + 004F @@DPS_Got_len: + + 004F E3 07 jcxz @DPS_Exit ; Don't Print if empty + + 0051 BB 0001 mov BX, 1 ; 1= DOS Handle for Display + 0054 B4 40 mov AH, 40h ; Write Text Function + 0056 CD 21 int 21h ; Call DOS to do it + + 0058 @DPS_Exit: + 0058 FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 0059 5F 1 pop DI ; Restore R1 + 005A 5E 2 pop SI ; Restore R1 + 005B 1F 3 pop DS ; Restore R1 + 005C 5D 4 pop BP ; Restore R1 + 005D CA 0002 ret 2 ; Exit & Clean Up Stack + + 0060 DOS_PRINTS ENDP + + + ;========================================= + ;void far pascal set_video_mode (int Mode) + ;========================================= + ; + ; Sets the Video Mode through the BIOS + ; + + PUBLIC SET_VIDEO_MODE + + 000E SVM_Stack STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 00 00 SVM_Mode DB ?,? ; Desired Video Mode + SVM_Stack ENDS + + + 0060 SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0060 55 1 push BP ; Save R1 + 0061 1E 2 push DS ; Save R1 + 0062 56 3 push SI ; Save R1 + 0063 57 4 push DI ; Save R1 + 0064 8B EC mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + 0066 32 E4 1 xor AH, AH ; Set Register = 0 + 0068 8A 46 0C mov AL, [BP].SVM_Mode ; Get Mode # + + 006B CD 10 int 10H ; Change Video Modes + + 006D @SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + 006D 5F 1 pop DI ; Restore R1 + 006E 5E 2 pop SI ; Restore R1 + 006F 1F 3 pop DS ; Restore R1 + 0070 5D 4 pop BP ; Restore R1 + 0071 CA 0002 ret 2 ; Exit & Clean Up Stack + + 0074 SET_VIDEO_MODE ENDP + + + ;=================================== + ;int far pascal scan_keyboard (void) + ;=================================== + ; + ; Function to scan keyboard for a pressed key + ; + + PUBLIC SCAN_KEYBOARD + + 0074 SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0074 55 1 push BP ; Save R1 + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Page 2 - 1 + + + 0075 1E 2 push DS ; Save R1 + 0076 56 3 push SI ; Save R1 + 0077 57 4 push DI ; Save R1 + + 0078 B4 01 mov AH, 01H ; Function #1 + 007A CD 16 INT 16H ; Call Keyboard Driver + 007C 74 0C JZ @SK_NO_KEY ; Exit if Zero flag set + + 007E B4 00 mov AH, 00H ; Remove Key from Buffer + 0080 CD 16 INT 16H ; Get Keycode in AX + + 0082 0A C0 OR AL, AL ; Low Byte Set (Ascii?) + 0084 74 06 JZ @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + 0086 32 E4 1 xor AH, AH ; Set Register = 0 + 0088 EB 02 JMP s @SK_Exit ; Return Key in AX + + 008A @SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + 008A 33 C0 1 xor AX, AX ; Set Register = 0 + + 008C @SK_Exit: + 008C FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 008D 5F 1 pop DI ; Restore R1 + 008E 5E 2 pop SI ; Restore R1 + 008F 1F 3 pop DS ; Restore R1 + 0090 5D 4 pop BP ; Restore R1 + 0091 CB ret ; Exit & Clean Up Stack + + 0092 SCAN_KEYBOARD ENDP + + + ;======================================== + ;int far pascal random_int (int MaxValue) + ;======================================== + ; + ; Returns a pseudo-random number in the range of (0.. MaxInt-1) + ; + + + PUBLIC RANDOM_INT + + 0008 RI_Stack STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 RI_MaxVal DW ? ; Maximum Value to Return + 1 + RI_Stack ENDS + + + 0092 RANDOM_INT PROC FAR + + 0092 55 push BP ; Preserve Important Registers + 0093 8B EC mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + 0095 33 DB 1 xor BX, BX ; Set Register = 0 + CLR CX ; CX is the accumulator + 0097 33 C9 1 xor CX, CX ; Set Register = 0 + + REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values + ENDM + 0099 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 009D F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00A1 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00A5 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00A9 03 CA 1 add CX, DX ; add it into the accumulator + 00AB 43 1 inc BX + 00AC 43 1 inc BX ; point to the next set of values + 00AD 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 00B1 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00B5 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00B9 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00BD 03 CA 1 add CX, DX ; add it into the accumulator + 00BF 43 1 inc BX + 00C0 43 1 inc BX ; point to the next set of values + 00C1 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 00C5 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00C9 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00CD 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00D1 03 CA 1 add CX, DX ; add it into the accumulator + 00D3 43 1 inc BX + 00D4 43 1 inc BX ; point to the next set of values + + 00D5 8B C1 mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + 00D7 33 D2 1 xor DX, DX ; Set Register = 0 + 00D9 F7 76 06 div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + 00DC 8B C2 mov AX, DX + + 00DE 5D pop BP ; Restore BP + 00DF CA 0002 ret 2 ; back to BASIC with AX holding the result + + 00E2 RANDOM_INT ENDP + + + ;================================== + ;void far pascal init_random (void) + ;================================== + ; + ; Scrambles the psuedo-random number sequence + ; (XOR's the seed value with the timer) + ; + + PUBLIC INIT_RANDOM + + 00E2 INIT_RANDOM PROC FAR + + CLR AX ; Segment = 0000 + 00E2 33 C0 1 xor AX, AX ; Set Register = 0 + 00E4 8E C0 mov ES, AX + 00E6 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word + + 00EA 31 06 0000 R xor RND_Seed, AX ; Scramble 1st Seed + + 00EE CB ret ; Exit & Clean Up Stack + + 00EF INIT_RANDOM ENDP + + ;========================================= + ;int far pascal int_sqr (int X, int Round) + ;========================================= + ; + ; Returns the Integer Square Root of (X) + ; Round allows the return value to be rounded to the + ; nearest integer value by passing 0x80. Passing 0 + ; return the Integer Portion only. The rounding amound is + ; a number from 0 to 1 multiplied by 256, thus + ; 0.5 * 0x100 = 0x80! + ; + + 000C ISQ_Stack STRUC + 0000 0000 0000 DW ?,? ; BP, DI + 0004 00000000 DD ? ; Caller + 0008 0000 ISQ_Round DW ? ; Amount to Round Result * 256 + 000A 0000 ISQ_X DW ? ; "X" + ISQ_Stack ENDS + + PUBLIC INT_SQR + + 00EF INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + 00EF 55 1 push BP ; Save R1 + 00F0 57 2 push DI ; Save R1 + 00F1 8B EC mov BP, SP ; Set up Stack Frame + + 00F3 33 C0 xor AX, AX ; {xor eax,eax} + 00F5 33 D2 xor DX, DX ; {xor edx,edx} + 00F7 8B 7E 0A mov DI, [BP].ISQ_X ; {mov edi,x} + + 00FA B9 0010 mov CX, 16 ; {mov cx, 32} + + 00FD @ISQ_L: + + 00FD D1 E7 shl DI, 1 ; {shl edi,1} + 00FF D1 D2 rcl DX, 1 ; {rcl edx,1} + 0101 D1 E7 shl DI, 1 ; {shl edi,1} + 0103 D1 D2 rcl DX, 1 ; {rcl edx,1} + 0105 D1 E0 shl AX, 1 ; {shl eax,1} + 0107 8B D8 mov BX, AX ; {mov ebx,eax} + 0109 D1 E3 shl BX, 1 ; {shl ebx,1} + 010B 43 inc BX ; {inc ebx} + 010C 3B D3 cmp DX, BX ; {cmp edx,ebx} + 010E 7C 03 jl @ISQ_S + + 0110 2B D3 sub DX, BX ; {sub edx,ebx} + 0112 40 inc AX ; {inc eax} + + 0113 @ISQ_S: + 0113 E2 E8 loop @ISQ_L + + 0115 03 46 08 add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0 + .5} + 0118 C1 E8 08 shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + 011B 5F 1 pop DI ; Restore R1 + 011C 5D 2 pop BP ; Restore R1 + 011D CA 0004 ret 4 ; Exit + + 0120 INT_SQR ENDP + + ;================================= + ;int far pascal timer_count (void) + ;================================= + ; + ; Returns the current timer value as an integer/long integer + ; + + PUBLIC TIMER_COUNT + + 0120 TIMER_COUNT PROC FAR + + CLR AX ; Segment = 0000 + 0120 33 C0 1 xor AX, AX ; Set Register = 0 + 0122 8E C0 mov ES, AX + 0124 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word + 0128 26: 8B 16 046E mov DX, ES:[046Eh] ; Get Timer Hi Word + 012D CB ret ; Exit & Clean Up Stack + + 012E TIMER_COUNT ENDP + + + END + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 3 - 1 + + + + +Macros: + + N a m e Type + +CLR . . . . . . . . . . . . . . Proc +LOOPjz . . . . . . . . . . . . . Proc +LOOPx . . . . . . . . . . . . . Proc +POPx . . . . . . . . . . . . . . Proc +PUSHx . . . . . . . . . . . . . Proc + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 4 - 1 + + + + +Structures and Unions: + + N a m e Size + Offset Type + +DP_Stack . . . . . . . . . . . . 0010 + DP_Text . . . . . . . . . . . 000C DWord +ISQ_Stack . . . . . . . . . . . 000C + ISQ_Round . . . . . . . . . . 0008 Word + ISQ_X . . . . . . . . . . . . 000A Word +RI_Stack . . . . . . . . . . . . 0008 + RI_MaxVal . . . . . . . . . . 0006 Word +SVM_Stack . . . . . . . . . . . 000E + SVM_Mode . . . . . . . . . . . 000C Byte + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 5 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +C_UTILS_TEXT . . . . . . . . . . 16 Bit 012E Word Public 'CODE' +DGROUP . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 16 Bit 0014 Word Public 'DATA' + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 6 - 1 + + + + +Procedures, parameters and locals: + + N a m e Type Value Attr + +DOS_PRINTS . . . . . . . . . . . P Far 0039 C_UTILS_TEXT Length= 0027 Public +DOS_PRINT . . . . . . . . . . . P Far 0000 C_UTILS_TEXT Length= 0039 Public +INIT_RANDOM . . . . . . . . . . P Far 00E2 C_UTILS_TEXT Length= 000D Public +INT_SQR . . . . . . . . . . . . P Far 00EF C_UTILS_TEXT Length= 0031 Public +RANDOM_INT . . . . . . . . . . . P Far 0092 C_UTILS_TEXT Length= 0050 Public +SCAN_KEYBOARD . . . . . . . . . P Far 0074 C_UTILS_TEXT Length= 001E Public +SET_VIDEO_MODE . . . . . . . . . P Far 0060 C_UTILS_TEXT Length= 0014 Public +TIMER_COUNT . . . . . . . . . . P Far 0120 C_UTILS_TEXT Length= 000E Public + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 7 - 1 + + + + +Symbols: + + N a m e Type Value Attr + +?x3 . . . . . . . . . . . . . . Text ?,?,? +?x4 . . . . . . . . . . . . . . Text ?,?,?,? +@@DPS_Got_len . . . . . . . . . L Near 004F C_UTILS_TEXT +@@DPS_Scan_it . . . . . . . . . L Near 0046 C_UTILS_TEXT +@@DP_Got_len . . . . . . . . . . L Near 0016 C_UTILS_TEXT +@@DP_Scan_it . . . . . . . . . . L Near 000D C_UTILS_TEXT +@CodeSize . . . . . . . . . . . Number 0001h +@DPS_Exit . . . . . . . . . . . L Near 0058 C_UTILS_TEXT +@DataSize . . . . . . . . . . . Number 0000h +@ISQ_L . . . . . . . . . . . . . L Near 00FD C_UTILS_TEXT +@ISQ_S . . . . . . . . . . . . . L Near 0113 C_UTILS_TEXT +@Interface . . . . . . . . . . . Number 0000h +@Model . . . . . . . . . . . . . Number 0004h +@No_Print . . . . . . . . . . . L Near 001F C_UTILS_TEXT +@SK_Exit . . . . . . . . . . . . L Near 008C C_UTILS_TEXT +@SK_NO_KEY . . . . . . . . . . . L Near 008A C_UTILS_TEXT +@SVM_Exit . . . . . . . . . . . L Near 006D C_UTILS_TEXT +@code . . . . . . . . . . . . . Text C_UTILS_TEXT +@data . . . . . . . . . . . . . Text DGROUP +@fardata? . . . . . . . . . . . Text FAR_BSS +@fardata . . . . . . . . . . . . Text FAR_DATA +@stack . . . . . . . . . . . . . Text DGROUP +CR_LF . . . . . . . . . . . . . Byte 0012 _DATA +False . . . . . . . . . . . . . Number 0000h +RND_ModV . . . . . . . . . . . . Word 000C _DATA +RND_Mult . . . . . . . . . . . . Word 0006 _DATA +RND_Seed . . . . . . . . . . . . Word 0000 _DATA +True . . . . . . . . . . . . . . Number -0001h +b . . . . . . . . . . . . . . . Text BYTE PTR +d . . . . . . . . . . . . . . . Text DWORD PTR +f . . . . . . . . . . . . . . . Text FAR PTR +nil . . . . . . . . . . . . . . Number 0000h +o . . . . . . . . . . . . . . . Text OFFSET +s . . . . . . . . . . . . . . . Text SHORT +w . . . . . . . . . . . . . . . Text WORD PTR + + 0 Warnings + 0 Errors diff --git a/src/lib/modex/c_utils.sbr b/src/lib/modex/c_utils.sbr new file mode 100755 index 00000000..0301171b Binary files /dev/null and b/src/lib/modex/c_utils.sbr differ diff --git a/src/lib/modex/demos/basic7/chardemo.bas b/src/lib/modex/demos/basic7/chardemo.bas new file mode 100755 index 00000000..627e3278 --- /dev/null +++ b/src/lib/modex/demos/basic7/chardemo.bas @@ -0,0 +1,164 @@ +DEFINT A-Z +DECLARE SUB PRINT.STRING (Text$, Xpos%, Ypos%, Colour%) +DECLARE FUNCTION MakePal$ (Red%, Green%, Blue%) +DECLARE SUB LOAD.FONT (FontFile$, FontNum%) +DECLARE SUB ERROR.OUT (Text$) + + REM $INCLUDE: 'MODEX.BI' + + REM $INCLUDE: 'UTILS.BI' + +TYPE FONT + SetData AS STRING * 1024 +END TYPE + + +TYPE VGAPalette + PalData AS STRING * 768 +END TYPE + + + ' Alternate form of LOAD_DAC_REGISTERS so we can pass an offset into + ' a String instead of the Address of the String + +DECLARE SUB LOAD.DACS ALIAS "LOAD_DAC_REGISTERS" (BYVAL Addr&, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) + + + ' + 'MODE X DEMO of Multiple Character Sets and Block Color Cycling + ' + 'By Matt Pritchard + ' + +COMMON SHARED CharSet() AS FONT + +DIM Pal AS VGAPalette + + REM $DYNAMIC + +DIM SHARED CharSet(0 TO 3) AS FONT + + + LOAD.FONT "SYSTEM.FNT", 0 + LOAD.FONT "ROM_8x8.FNT", 1 + LOAD.FONT "SPACEAGE.FNT", 2 + + + IF SET.MODEX(Mode320x240) = False THEN + ERROR.OUT "ERROR SETTING MODE X" + END IF + + + A$ = "": B$ = "" + FOR X = 0 TO 31: A$ = A$ + MakePal$(31 - X, X, 0): NEXT X + FOR X = 0 TO 31: A$ = A$ + MakePal$(0, 31 - X, X): NEXT X + FOR X = 0 TO 31: A$ = A$ + MakePal$(X, 0, 31 - X): NEXT X + + FOR X = 0 TO 31: B$ = B$ + MakePal$(31 - X, X, X): NEXT X + FOR X = 0 TO 31: B$ = B$ + MakePal$(X, 31 - X, X): NEXT X + FOR X = 0 TO 31: B$ = B$ + MakePal$(X, X, 31 - X): NEXT X + + Black$ = STRING$(192, 0) + White$ = STRING$(128 * 3, 48) + + Pal1$ = Black$ + A$ + A$ + B$ + B$ + A$ + + LOAD.DACS SSEGADD(Black$), 64, 127, 1 + LOAD.DACS SSEGADD(Black$), 20, 63, 0 + + LOAD.DACS SSEGADD(White$), 128, 255, 0 + + '*** Background *** + + FOR X = 0 TO 319 + FOR Y = 0 TO 239 + IF ((X + Y) AND 1) = 1 THEN SET.POINT X, Y, 64 + X \ 5 ELSE SET.POINT X, Y, 20 + Y \ 6 + NEXT Y + NEXT X + + '*** Draw Font Displays *** + + PRINT.STRING "FONT: SYSTEM.FNT", 11, 7, 15 + PRINT.STRING "FONT: ROM_8x8.FNT", 11, 17, 15 + PRINT.STRING "FONT: SPACEAGE.FNT", 11, 27, 15 + PRINT.STRING "PRESS ANY KEY TO CONTINUE", 8, 29, 14 + + + FOR F = 0 TO 2 + SET.DISPLAY.FONT CharSet(F), 1 + Yp = F * 80 + 10 + FOR Y = 0 TO 96 STEP 32 + FOR X = 0 TO 31 + TGPRINTC 128 + Y + X, X * 10 + 1, Yp, 128 + Y + NEXT X + Yp = Yp + 10 + NEXT Y + NEXT F + + DO + LOOP UNTIL SCAN.KEYBOARD + + Offset = 0 + Restart = 192 + MaxOfs = 192 + 96 * 6 + + Delay = 100 + + Offset2 = 0 + Offset2Dir = 3 + Offset2Min = 192 + Offset2Max = Offset2Min + 192 * 6 + + DO + LOAD.DACS SSEGADD(Pal1$) + Offset, 64, 127, 1 + Offset = Offset + 3 + IF Offset >= MaxOfs THEN Offset = Restart + IF Delay THEN + Delay = Delay - 1 + ELSE + LOAD.DACS SSEGADD(Pal1$) + Offset2, 20, 60, 0 + IF Offset2 = Offset2Max THEN Offset2Dir = -3 + IF Offset2 = Offset2Min THEN Offset2Dir = 3 + Offset2 = Offset2 + Offset2Dir + END IF + + LOOP UNTIL SCAN.KEYBOARD + + ERROR.OUT "DEMO OVER" + +REM $STATIC +SUB ERROR.OUT (Text$) + + SET.VIDEO.MODE 3 + + DOS.PRINT Text$ + + END + +END SUB + +SUB LOAD.FONT (FontFile$, FontNum) STATIC + + IF LEN(DIR$(FontFile$)) = 0 THEN ERROR.OUT "FILE NOT FOUND: " + FontFile$ + + OPEN FontFile$ FOR BINARY AS #1 + + SEEK #1, 1 + GET #1, , CharSet(FontNum) + + CLOSE #1 + +END SUB + +FUNCTION MakePal$ (Red, Green, Blue) STATIC + + MakePal$ = CHR$(Red) + CHR$(Green) + CHR$(Blue) + +END FUNCTION + +SUB PRINT.STRING (Text$, Xpos, Ypos, Colour) + + TPRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos * 8, Ypos * 8, Colour + +END SUB + diff --git a/src/lib/modex/demos/basic7/make-lib.bat b/src/lib/modex/demos/basic7/make-lib.bat new file mode 100755 index 00000000..fc0b3b5c --- /dev/null +++ b/src/lib/modex/demos/basic7/make-lib.bat @@ -0,0 +1,5 @@ +ECHO ... Building MODEX.QLB for BASIC PDS 7.1 +LIB MODEX -+MODEX,, +LIB MODEX -+UTILS,, +DEL MODEX.BAK +LINK /Q MODEX+UTILS, MODEX.QLB, NUL, C:\BC7\LIB\QBXQLB.LIB; diff --git a/src/lib/modex/demos/basic7/modex.bi b/src/lib/modex/demos/basic7/modex.bi new file mode 100755 index 00000000..6b1d7afe --- /dev/null +++ b/src/lib/modex/demos/basic7/modex.bi @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/src/lib/modex/demos/basic7/modex.qlb b/src/lib/modex/demos/basic7/modex.qlb new file mode 100755 index 00000000..70d22db3 Binary files /dev/null and b/src/lib/modex/demos/basic7/modex.qlb differ diff --git a/src/lib/modex/demos/basic7/test6.bas b/src/lib/modex/demos/basic7/test6.bas new file mode 100755 index 00000000..220a67ba --- /dev/null +++ b/src/lib/modex/demos/basic7/test6.bas @@ -0,0 +1,562 @@ +'File: TEST6.BAS +'Descp.: A Mode "X" demonstration +'Author: Matt Pritchard +'Date: 14 April, 1993 +' +DECLARE SUB DEMO.RES (Mode%, Xmax%, Ymax%) +DECLARE SUB ERROR.OUT (Message$) +DECLARE FUNCTION GET.KEY% () +DECLARE SUB LOAD.SHAPES () +DECLARE SUB PAGE.DEMO () +DECLARE SUB PRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%, ColorB%) +DECLARE SUB TPRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%) +DEFINT A-Z + + +TYPE ShapeType + ImgData AS STRING * 512 + xWidth AS INTEGER + yWidth AS INTEGER +END TYPE + +TYPE Sprite + Xpos AS INTEGER + Ypos AS INTEGER + XDir AS INTEGER + YDir AS INTEGER + Shape AS INTEGER +END TYPE + + +CONST MaxShapes = 32 + + REM $INCLUDE: 'UTILS.BI' + REM $INCLUDE: 'MODEX.BI' + +DIM SHARED Img(32) AS ShapeType +COMMON SHARED Img() AS ShapeType + + + CALL INIT.RANDOM + + CALL LOAD.SHAPES + + CALL DEMO.RES(Mode320x200, 320, 200) + CALL DEMO.RES(Mode320x400, 320, 400) + + CALL DEMO.RES(Mode360x200, 360, 200) + CALL DEMO.RES(Mode360x400, 360, 400) + + CALL DEMO.RES(Mode320x240, 320, 240) + CALL DEMO.RES(Mode320x480, 320, 480) + + CALL DEMO.RES(Mode360x240, 360, 240) + CALL DEMO.RES(Mode360x480, 360, 480) + + CALL PAGE.DEMO + + SET.VIDEO.MODE 3 + DOS.PRINT "THIS MODE X DEMO IS FINISHED" + END + +SUB DEMO.RES (Mode, Xmax, Ymax) + + IF SET.MODEX%(Mode) = 0 THEN + ERROR.OUT "Unable to SET_MODEX" + STR$(Mode) + END IF + + XCenter = Xmax \ 2 + + X1 = 10 + Y1 = 10 + X2 = Xmax - 1 + Y2 = Ymax - 1 + + FOR Z = 0 TO 3 + Colr = 31 - Z * 2 + DRAW.LINE X1 + Z, Y1 + Z, X2 - Z, Y1 + Z, Colr + DRAW.LINE X1 + Z, Y1 + Z, X1 + Z, Y2 - Z, Colr + DRAW.LINE X1 + Z, Y2 - Z, X2 - Z, Y2 - Z, Colr + DRAW.LINE X2 - Z, Y1 + Z, X2 - Z, Y2 - Z, Colr + NEXT Z + + XChars = Xmax \ 10 + YChars = Ymax \ 10 + + FOR X = 0 TO XChars - 1 + TGPRINTC 48 + ((X + 1) MOD 10), X * 10 + 1, 1, 9 + ((X \ 8) MOD 7) + DRAW.LINE X * 10 + 9, 0, X * 10 + 9, 3, 15 + NEXT X + + FOR Y = 0 TO YChars - 1 + TGPRINTC 48 + ((Y + 1) MOD 10), 1, Y * 10 + 1, 9 + ((Y \ 10) MOD 7) + DRAW.LINE 0, Y * 10 + 9, 3, Y * 10 + 9, 15 + NEXT Y + + ' Draw Lines + + FOR X = 0 TO 63 + N = 15 + X * .75 + SET.DAC.REGISTER 64 + X, N, N, N + SET.DAC.REGISTER 128 + X, 0, N, N + + DRAW.LINE 103 - X, 60, 40 + X, 123, 64 + X + DRAW.LINE 40, 60 + X, 103, 123 - X, 128 + X + + NEXT X + TPRINT.TEXT "LINE TEST", 37, 130, c.BLUE + + Y = 60: Gap = 0 + FOR X = 0 TO 9 + FILL.BLOCK 120, Y, 120 + X, Y + Gap, 64 + X + FILL.BLOCK 140 - (15 - X), Y, 150 + X, Y + Gap, 230 + X + FILL.BLOCK 170 - (15 - X), Y, 170, Y + Gap, 128 + X + Y = Y + Gap + 2 + Gap = Gap + 1 + NEXT X + TPRINT.TEXT "FILL TEST", 110, 46, c.GREEN + + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + SET.POINT X, Y, X + Y + X + Y + NEXT Y + NEXT X + + TPRINT.TEXT "PIXEL TEST", 182, 130, c.RED + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + IF READ.POINT(X, Y) <> ((X + Y + X + Y) AND 255) THEN + ERROR.OUT "READ.PIXEL Failure" + END IF + NEXT Y + NEXT X + + + + Msg$ = " This is a MODE X demo " + PRINT.TEXT Msg$, XCenter - (LEN(Msg$) * 4), 20, c.bRED, c.BLUE + Msg$ = "Screen Resolution is by " + Xp = XCenter - (LEN(Msg$) * 4) + PRINT.TEXT Msg$, Xp, 30, c.bGREEN, c.BLACK + + PRINT.TEXT LTRIM$(STR$(Xmax)), Xp + 8 * 21, 30, c.bPURPLE, c.BLACK + PRINT.TEXT LTRIM$(STR$(Ymax)), Xp + 8 * 28, 30, c.bWHITE, c.BLACK + + FOR X = 0 TO 15 + SET.DAC.REGISTER 230 + X, 63 - X * 4, 0, 15 + X * 3 + DRAW.LINE 30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X + NEXT X + TPRINT.TEXT "Press to Continue", XCenter - (26 * 4), Ymax - 18, c.YELLOW + + X = GET.KEY% + IF X = KyESC THEN ERROR.OUT "ABORT" + +END SUB + +SUB ERROR.OUT (Message$) + + SET.VIDEO.MODE 3 + DOS.PRINT Message$ + END + +END SUB + +FUNCTION GET.KEY% + + DO + X = SCAN.KEYBOARD + LOOP UNTIL X + + GET.KEY% = X + +END FUNCTION + +SUB LOAD.SHAPES + +DIM Grid(1 TO 32, 1 TO 32) + + FOR Shape = 0 TO MaxShapes - 1 + + FOR Y = 1 TO 32 + FOR X = 1 TO 32 + Grid(X, Y) = 0 + NEXT X + NEXT Y + + Style = RANDOM.INT(6) + Colour = 1 + RANDOM.INT(15) + + SELECT CASE Style + + CASE 0: ' Solid Box + + DO + xWidth = 3 + RANDOM.INT(30) + yWidth = 3 + RANDOM.INT(30) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + CASE 1: ' Hollow Box + + DO + xWidth = 5 + RANDOM.INT(28) + yWidth = 5 + RANDOM.INT(28) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + HollowX = 1 + RANDOM.INT(xWidth \ 2 - 1) + HollowY = 1 + RANDOM.INT(yWidth \ 2 - 1) + + FOR Y = HollowY + 1 TO yWidth - HollowY + FOR X = HollowX + 1 TO xWidth - HollowX + Grid(X, Y) = nil + NEXT X + NEXT Y + + CASE 2: ' Solid Diamond + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + NEXT X + NEXT Y + + + CASE 3: ' Hollow Diamond + + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + sWidth = RANDOM.INT(Centre) + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + IF X + (Centre - Y) >= sWidth THEN + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + END IF + NEXT X + NEXT Y + + CASE 4: ' Ball + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + CASE 5: ' Ball + + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + sWidth = RANDOM.INT(xWidth) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre AND D >= sWidth THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + END SELECT + + Img(Shape).xWidth = xWidth + Img(Shape).yWidth = yWidth + + A$ = STRING$(xWidth * yWidth, nil) + + c = 1 + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + MID$(A$, c, 1) = CHR$(Grid(X, Y)) + c = c + 1 + NEXT X + NEXT Y + + Img(Shape).ImgData = A$ + + + NEXT Shape + +END SUB + +SUB PAGE.DEMO + +CONST MaxSprites = 64 + +DIM Obj(MaxSprites) AS Sprite +DIM LastX(MaxSprites, 1), LastY(MaxSprites, 1) +DIM LastObjects(1) + + ScreenX = 360: ScreenY = 240 + + IF SET.VGA.MODEX%(Mode320x200, ScreenX, ScreenY, 3) = 0 THEN + ERROR.OUT "Unable to SET_VGA_MODEX" + STR$(Mode) + END IF + + SET.ACTIVE.PAGE 0 + + CLEAR.VGA.SCREEN c.BLACK + + PRINT.TEXT "This is a Test of the Following Functions:", 10, 9, c.bWHITE, c.BLACK + + DRAW.LINE 10, 18, 350, 18, c.YELLOW + PRINT.TEXT "SET_ACTIVE_PAGE", 10, 20, c.bBLUE, c.BLACK + PRINT.TEXT "SET_DISPLAY_PAGE", 10, 30, c.GREEN, c.BLACK + PRINT.TEXT "SET_DAC_REGISTER", 10, 40, c.RED, c.BLACK + PRINT.TEXT "CLEAR_VGA_SCREEN", 10, 50, c.CYAN, c.BLACK + + PRINT.TEXT "TDRAW_BITMAP", 10, 60, c.PURPLE, c.BLACK + PRINT.TEXT "COPY_PAGE", 10, 70, c.GREEN, c.BLACK + PRINT.TEXT "COPY_BITMAP", 10, 80, c.CYAN, c.BLACK + + PRINT.TEXT "GPRINTC", 10, 90, c.BLUE, c.BLACK + PRINT.TEXT "TGPRINTC", 10, 100, c.GREEN, c.BLACK + PRINT.TEXT "SET_WINDOW", 10, 110, c.RED, c.BLACK + + PRINT.TEXT "VIRTUAL SCREEN SIZES", 190, 20, c.bBLUE, c.BLACK + PRINT.TEXT " SMOOTH SCROLLING", 190, 30, c.GREEN, c.BLACK + PRINT.TEXT " SPRITE ANIMATION", 190, 40, c.CYAN, c.BLACK + PRINT.TEXT " PAGE FLIPPING", 190, 50, c.RED, c.BLACK + PRINT.TEXT " COLOR CYCLING", 190, 60, c.PURPLE, c.BLACK + + + FOR X = 0 TO 60 + SET.DAC.REGISTER 50 + X, 3 + X, 0, 60 - X + SET.DAC.REGISTER 150 + X, 3 + X, 0, 60 - X + NEXT X + + c = 0: DC = 1 + FOR X = 0 TO ScreenX \ 2 + DRAW.LINE ScreenX \ 2 - 1, ScreenY \ 4, X, ScreenY - 1, c + 50 + DRAW.LINE ScreenX \ 2, ScreenY \ 4, ScreenX - X - 1, ScreenY - 1, c + 50 + c = c + DC + IF c = 0 OR c = 60 THEN DC = -DC + NEXT X + + TPRINT.TEXT "Press to Continue", 72, 190, c.bWHITE + TPRINT.TEXT "< > = Faster < > = Slower", 72, 204, c.bGREEN + TPRINT.TEXT "< > = Fewer Shapes < > = More Shapes", 32, 218, c.bCYAN + + TGPRINTC 43, 80, 204, c.YELLOW + TGPRINTC 45, 200, 204, c.YELLOW + + TGPRINTC 25, 40, 218, c.YELLOW + TGPRINTC 24, 200, 218, c.YELLOW + + COPY.PAGE 0, 1 + COPY.PAGE 0, 2 + + FOR X = 1 TO MaxSprites + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + + Obj(X).Shape = X MOD MaxShapes + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + Obj(X).Xpos = 1 + RANDOM.INT(ScreenX - SpriteX - 2) + Obj(X).Ypos = 1 + RANDOM.INT(ScreenY - SpriteY - 2) + + LastX(X, 0) = Obj(X).Xpos + LastX(X, 1) = Obj(X).Xpos + LastY(X, 0) = Obj(X).Ypos + LastY(X, 1) = Obj(X).Ypos + NEXT X + + CurrentPage = 0 + + 'View Shift... + + ViewX = 0 + ViewY = 0 + ViewMax = 3 + ViewCnt = 0 + ViewXD = 1 + ViewYD = 1 + + SetColor = 3: SDir = 1 + PrevColor = 0: PDir = 1 + + VisObjects = MaxSprites \ 2 + LastObjects(0) = 0 + LastObjects(1) = 0 + +DRAW.LOOP: + + + SET.ACTIVE.PAGE CurrentPage + + ' Erase Old Images + + FOR X = 1 TO LastObjects(CurrentPage) + + X1 = LastX(X, CurrentPage) AND &HFFFC + Y1 = LastY(X, CurrentPage) + X2 = ((LastX(X, CurrentPage) + Img(Obj(X).Shape).xWidth)) OR 3 + Y2 = Y1 + Img(Obj(X).Shape).yWidth - 1 + + COPY.BITMAP 2, X1, Y1, X2, Y2, CurrentPage, X1, Y1 + + NEXT X + + ' Draw new images + + FOR X = 1 TO VisObjects + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + ' Move Sprite + +REDOX: + NewX = Obj(X).Xpos + Obj(X).XDir + IF NewX < 0 OR NewX + SpriteX > ScreenX THEN + Obj(X).XDir = -Obj(X).XDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOX + END IF + END IF + Obj(X).Xpos = Obj(X).Xpos + Obj(X).XDir + +REDOY: + NewY = Obj(X).Ypos + Obj(X).YDir + IF NewY < 0 OR NewY + SpriteY > ScreenY THEN + Obj(X).YDir = -Obj(X).YDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOY + END IF + END IF + Obj(X).Ypos = Obj(X).Ypos + Obj(X).YDir + + 'Draw Sprite + + TDRAW.BITMAP Img(Obj(X).Shape), Obj(X).Xpos, Obj(X).Ypos, SpriteX, SpriteY + + LastX(X, CurrentPage) = Obj(X).Xpos + LastY(X, CurrentPage) = Obj(X).Ypos + + NEXT X + + LastObjects(CurrentPage) = VisObjects + + ' Pan Screen Back & Forth + + ViewCnt = ViewCnt + 1 + IF ViewCnt >= ViewMax THEN + ViewX = ViewX + ViewXD + IF ViewX = 0 OR ViewX = 39 THEN ViewXD = -ViewXD + IF ViewXD < 0 THEN + ViewY = ViewY + ViewYD + IF ViewY = 0 OR ViewY = 39 THEN ViewYD = -ViewYD + END IF + + SET.WINDOW CurrentPage, ViewX, ViewY + + ViewCnt = 0 + ELSE + SET.DISPLAY.PAGE CurrentPage + END IF + + ' Cycle Colors + + SET.DAC.REGISTER 50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 50 + SetColor, SetColor, 10, 63 - SetColor + + SET.DAC.REGISTER 150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 150 + SetColor, 63, 63, SetColor + + SetColor = SetColor + SDir + IF SetColor = 60 OR SetColor = 0 THEN SDir = -SDir + + PrevColor = PrevColor + PDir + IF PrevColor = 60 OR PrevColor = 0 THEN PDir = -PDir + + CurrentPage = 1 - CurrentPage + + Code = SCAN.KEYBOARD + + IF Code = False THEN GOTO DRAW.LOOP + + IF Code = KyPlus THEN + IF ViewMax < 12 THEN ViewMax = ViewMax + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyMinus THEN + IF ViewMax > 1 THEN ViewMax = ViewMax - 1 + IF ViewCnt >= ViewMax THEN ViewCnt = 0 + GOTO DRAW.LOOP + END IF + + IF Code = KyUp THEN + IF VisObjects < MaxSprites THEN VisObjects = VisObjects + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyDown THEN + IF VisObjects > 1 THEN VisObjects = VisObjects - 1 + GOTO DRAW.LOOP + END IF + + +END SUB + +SUB PRINT.TEXT (Text$, Xpos, Ypos, ColorF, ColorB) + + IF LEN(Text$) = 0 THEN EXIT SUB + + PRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF, ColorB + + +END SUB + +SUB TPRINT.TEXT (Text$, Xpos, Ypos, ColorF) + + IF LEN(Text$) = 0 THEN EXIT SUB + + TPRINT.STR SSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF + +END SUB + diff --git a/src/lib/modex/demos/basic7/uasm-bc7.bat b/src/lib/modex/demos/basic7/uasm-bc7.bat new file mode 100755 index 00000000..5ad67fb5 --- /dev/null +++ b/src/lib/modex/demos/basic7/uasm-bc7.bat @@ -0,0 +1 @@ +MASM /DFARSTRINGS utils, utils, utils, nul; \ No newline at end of file diff --git a/src/lib/modex/demos/basic7/utils.asm b/src/lib/modex/demos/basic7/utils.asm new file mode 100755 index 00000000..811b8f8e --- /dev/null +++ b/src/lib/modex/demos/basic7/utils.asm @@ -0,0 +1,406 @@ +;======================================================= +;=== UTILS.ASM - Asm Utilities for QuickBasic/BC7 === +;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + +IFDEF FARSTRINGS + + EXTRN stringaddress:far + EXTRN stringlength:far + +ENDIF + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;================= +;DOS_PRINT (Text$) +;================= +; +; Prints Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DW ? ; Address of Text$ Descriptor +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;================== +;DOS_PRINTS (Text$) +;================== +; +; Print Text$ Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;====================== +;SET_VIDEO_MODE (Mode%) +;====================== +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;============== +;SCAN_KEYBOARD% +;============== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + + mov AH, 01H ; Function #1 + int 16H ; Call Keyboard Driver + jz @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + int 16H ; Get Keycode in AX + + or AL, AL ; Low Byte Set (Ascii?) + jz @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + jmp s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;==================== +;RANDOM_INT (MaxInt%) +;==================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;=========== +;INIT_RANDOM +;=========== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + + +;==================== +;INT_SQR (X%, Round%) +;==================== +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + ret 4 ; Exit + +INT_SQR ENDP + + +;============ +;TIMER_COUNT& +;============ +; +; Returns the current timer value as an integer/long integer +; + + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX ; use ES to get at data + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Return value in DX:AX + +TIMER_COUNT ENDP + + + END diff --git a/src/lib/modex/demos/basic7/utils.bi b/src/lib/modex/demos/basic7/utils.bi new file mode 100755 index 00000000..aeafeef4 --- /dev/null +++ b/src/lib/modex/demos/basic7/utils.bi @@ -0,0 +1,51 @@ + + ' Misc Constants + +CONST True = -1, False = 0, nil = 0 + + ' Keyboard Codes: Extended + +CONST KyF1 = &H3B00, KyF2 = &H3C00, KyF3 = &H3D00, KyF4 = &H3E00, KyF5 = &H3F00 +CONST KyF6 = &H4000, KyF7 = &H4100, KyF8 = &H4200, KyF9 = &H4300, KyF10 = &H4400 + +CONST KyUp = &H4800, KyLeft = &H4B00, KyRight = &H4D00, KyDown = &H5000 +CONST KySLeft = &HCB00, KySRight = &HCD00, KySUp = &HC800, KySDown = &HD000 + +CONST KyHome = &H4700, KyPgUp = &H4900, KyEnd = &H4F00, KyPgDn = &H5100 +CONST KySHome = &HC700, KySPgUp = &HC900, KySEnd = &HCF00, KySPgDn = &HD100 + +CONST KyIns = &H5200, KyDel = &H5300, KyRvsTab = &H8F00 +CONST KySIns = &HC200, KySDel = &HC300 + +CONST KyAltA = &H1E00, KyAltB = &H3000, KyAltC = &H2E00, KyAltD = &H2000 +CONST KyAltE = &H1200, KyAltF = &H2100, KyAltG = &H2200, KyAltH = &H2300 +CONST KyAltI = &H1700, KyAltJ = &H2400, KyAltK = &H2500, KyAltL = &H2600 +CONST KyAltM = &H3200, KyAltN = &H3100, KyAltO = &H1800, KyAltP = &H1900 +CONST KyAltQ = &H1000, KyAltR = &H1300, KyAltS = &H1F00, KyAltT = &H1400 +CONST KyAltU = &H1600, KyAltV = &H2F00, KyAltW = &H1100, KyAltX = &H2D00 +CONST KyAltY = &H1500, KyAltZ = &H2C00 + + ' Keyboard Codes: Ascii + +CONST KyBS = 8, KyTab = 9, KyCR = 13, KyESC = &H1B, KyClr = &H7F +CONST KyPlus = 45, KyMinus = 43 + + ' Color Constants + +CONST c.BLACK = 0, c.BLUE = 1, c.GREEN = 2, c.CYAN = 3 +CONST c.RED = 4, c.PURPLE = 5, c.BROWN = 6, c.WHITE = 7 +CONST c.GREY = 8, c.bBLUE = 9, c.bGREEN = 10, c.bCYAN = 11 +CONST c.bRED = 12, c.bPURPLE = 13, c.YELLOW = 14, c.bWHITE = 15 +CONST c.BRIGHT = 8 + + ' From UTILS.ASM + +DECLARE SUB DOS.PRINT ALIAS "DOS_PRINT" (Text$) +DECLARE SUB DOS.PRINTS ALIAS "DOS_PRINTS" (Text$) +DECLARE SUB SET.VIDEO.MODE ALIAS "SET_VIDEO_MODE" (BYVAL Mode%) +DECLARE FUNCTION SCAN.KEYBOARD% ALIAS "SCAN_KEYBOARD" +DECLARE FUNCTION RANDOM.INT ALIAS "RANDOM_INT" (BYVAL MaxInt%) +DECLARE SUB INIT.RANDOM ALIAS "INIT_RANDOM" +DECLARE FUNCTION TIMER.COUNT& ALIAS "TIMER_COUNT" +DECLARE FUNCTION INT.SQR ALIAS "INT_SQR" (BYVAL X%, BYVAL Round%) + diff --git a/src/lib/modex/demos/c/c_utils.asm b/src/lib/modex/demos/c/c_utils.asm new file mode 100755 index 00000000..01182013 --- /dev/null +++ b/src/lib/modex/demos/c/c_utils.asm @@ -0,0 +1,456 @@ +;======================================================= +;=== C_UTILS.ASM - Asm Utilities for C/C++ === +;======================================================= + + PAGE 255, 132 + + .MODEL Huge +; .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +; PUSHx MACRO R1, R2, R3, R4;, R5, R6, R7, R8 +; IFNB +; push R1 ; Save R1 +; PUSHx R2, R3, R4;, R5, R6, R7, R8 +; ENDIF +; ENDM +; +; POPx MACRO R1, R2, R3, R4;, R5, R6, R7, R8 +; IFNB +; pop R1 ; Restore R1 +; POPx R2, R3, R4;, R5, R6, R7, R8 +; ENDIF +; ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + ?x2 EQU + ?x1 EQU + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;=========================================== +;void far pascal dos_print (far char *Text) +;=========================================== +; +; - Print Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DD ? ; Far Address of Text to print +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DP_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DP_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DP_Scan_it ; check again... + +@@DP_Got_len: + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 4 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;=========================================== +;void far pascal dos_prints (char far *Text) +;=========================================== +; +; Print Text Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + mov SI, DX ; DS:SI = String data + +@@DPS_Scan_it: + + cmp b [SI], 0 ; Null Byte found? + je @@DPS_Got_Len ; exit loop if so + + inc CX ; Len++ + inc SI ; Point to next char + jmp s @@DPS_Scan_it ; check again... + +@@DPS_Got_len: + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;========================================= +;void far pascal set_video_mode (int Mode) +;========================================= +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;=================================== +;int far pascal scan_keyboard (void) +;=================================== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + + mov AH, 01H ; Function #1 + INT 16H ; Call Keyboard Driver + JZ @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + INT 16H ; Get Keycode in AX + + OR AL, AL ; Low Byte Set (Ascii?) + JZ @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + JMP s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;======================================== +;int far pascal random_int (int MaxValue) +;======================================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;================================== +;void far pascal init_random (void) +;================================== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + +;========================================= +;int far pascal int_sqr (int X, int Round) +;========================================= +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + ;PUSHx BP, DI ; Save BP + push bp + push di + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + shr ax, 1 ; {shr eax,16} {to ax (result)} + + ;POPx DI, BP ; Restore Registers + pop di + pop bp + ret 4 ; Exit + +INT_SQR ENDP + +;================================= +;int far pascal timer_count (void) +;================================= +; +; Returns the current timer value as an integer/long integer +; + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + CLR AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Clean Up Stack + +TIMER_COUNT ENDP + + + END diff --git a/src/lib/modex/demos/c/c_utils.h b/src/lib/modex/demos/c/c_utils.h new file mode 100755 index 00000000..9be6ba2d --- /dev/null +++ b/src/lib/modex/demos/c/c_utils.h @@ -0,0 +1,117 @@ + +#ifndef __C_UTILS_H +#define __C_UTILS_H + + + /* Misc Constants */ + +#define True -1 +#define False 0 +#define nil 0 + + /* Color Constants */ + +#define c_BLACK 0 +#define c_BLUE 1 +#define c_GREEN 2 +#define c_CYAN 3 +#define c_RED 4 +#define c_PURPLE 5 +#define c_BROWN 6 +#define c_WHITE 7 +#define c_GREY 8 +#define c_bBLUE 9 +#define c_bGREEN 10 +#define c_bCYAN 11 +#define c_bRED 12 +#define c_bPURPLE 13 +#define c_YELLOW 14 +#define c_bWHITE 15 +#define c_BRIGHT 16 + + +#define Ky_F1 0x3B00 +#define Ky_F2 0x3C00 +#define Ky_F3 0x3D00 +#define Ky_F4 0x3E00 +#define Ky_F5 0x3F00 +#define Ky_F6 0x4000 +#define Ky_F7 0x4100 +#define Ky_F8 0x4200 +#define Ky_F9 0x4300 +#define Ky_F10 0x4400 + +#define Ky_Up 0x4800 +#define Ky_Left 0x4B00 +#define Ky_Right 0x4D00 +#define Ky_Down 0x5000 +#define Ky_SUp 0xC800 +#define Ky_SLeft 0xCB00 +#define Ky_SRight 0xCD00 +#define Ky_SDown 0xD000 + +#define Ky_Home 0x4700 +#define Ky_End 0x4F00 +#define Ky_PgUp 0x4900 +#define Ky_PgDn 0x5100 +#define Ky_SHome 0xC700 +#define Ky_SEnd 0xCF00 +#define Ky_SPgUp 0xC900 +#define Ky_SPgDn 0xD100 + +#define Ky_Ins 0x5200 +#define Ky_Del 0x5300 +#define Ky_SIns 0xC200 +#define Ky_SDel 0xC300 + +#define Ky_Tab 0x0009 +#define Ky_RvsTab 0x8F00 +#define Ky_STab 0x8F00 + +#define Ky_BS 0x0008 +#define Ky_CR 0x000D +#define Ky_ESC 0x001B +#define Ky_Clr 0x007F + +#define Ky_Plus 0x002D +#define Ky_Minus 0x002B + +#define Ky_AltA 0x1E00 +#define Ky_AltB 0x3000 +#define Ky_AltC 0x2E00 +#define Ky_AltD 0x2000 +#define Ky_AltE 0x1200 +#define Ky_AltF 0x2100 +#define Ky_AltG 0x2200 +#define Ky_AltH 0x2300 +#define Ky_AltI 0x1700 +#define Ky_AltJ 0x2400 +#define Ky_AltK 0x2500 +#define Ky_AltL 0x2600 +#define Ky_AltM 0x3200 +#define Ky_AltN 0x3100 +#define Ky_AltO 0x1800 +#define Ky_AltP 0x1900 +#define Ky_AltQ 0x1000 +#define Ky_AltR 0x1300 +#define Ky_AltS 0x1F00 +#define Ky_AltT 0x1400 +#define Ky_AltU 0x1600 +#define Ky_AltV 0x2F00 +#define Ky_AltW 0x1100 +#define Ky_AltX 0x2D00 +#define Ky_AltY 0x1500 +#define Ky_AltZ 0x2C00 + + /* .ASM Functions From C_UTILS.ASM */ + +void far pascal dos_print (char far *Text); +void far pascal dos_prints (char far *Text); +void far pascal set_video_mode (int Mode); +int far pascal scan_keyboard (void); +int far pascal random_int (int MaxValue); +void far pascal init_random (void); +int far pascal int_sqr (int X, int Round); +int far pascal timer_count (void); + +#endif diff --git a/src/lib/modex/demos/c/c_utils.lst b/src/lib/modex/demos/c/c_utils.lst new file mode 100755 index 00000000..f9664ba0 --- /dev/null +++ b/src/lib/modex/demos/c/c_utils.lst @@ -0,0 +1,597 @@ +Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Page 1 - 1 + + + ;======================================================= + ;=== C_UTILS.ASM - Asm Utilities for C/C++ === + ;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + + PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + ; Macro to Clear a Register to 0 + + CLR MACRO Register + xor Register, Register ; Set Register = 0 + ENDM + + ; Macros to Decrement Counter & Jump on Condition + + LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 + ENDM + + LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 + ENDM + + + ; ==== General Constants ==== + + = 0000 False EQU 0 + =-0001 True EQU -1 + = 0000 nil EQU 0 + + = BYTE PTR b EQU BYTE PTR + = WORD PTR w EQU WORD PTR + = DWORD PTR d EQU DWORD PTR + = OFFSET o EQU OFFSET + = FAR PTR f EQU FAR PTR + = SHORT s EQU SHORT + = ?,?,?,? ?x4 EQU + = ?,?,? ?x3 EQU + + + 0000 .Data + + EVEN + + 0000 1CE5 7307 0322 RND_Seed DW 7397, 29447, 802 + 0006 00B3 00B7 00B6 RND_Mult DW 179, 183, 182 + 000C 8003 800B 800F RND_ModV DW 32771, 32779, 32783 + + 0012 0D 0A CR_LF DB 13, 10 ; the CRLF data + + 0000 .Code + + ;=========================================== + ;void far pascal dos_print (far char *Text) + ;=========================================== + ; + ; - Print Text Directly to DOS console w/ CR/LF + ; + + PUBLIC DOS_PRINT + + 0010 DP_Stack STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 00000000 DP_Text DD ? ; Far Address of Text to print + DP_Stack ENDS + + + 0000 DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0000 55 1 push BP ; Save R1 + 0001 1E 2 push DS ; Save R1 + 0002 56 3 push SI ; Save R1 + 0003 57 4 push DI ; Save R1 + 0004 8B EC mov BP, SP ; Set up Stack Frame + + 0006 C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + 0009 33 C9 1 xor CX, CX ; Set Register = 0 + 000B 8B F2 mov SI, DX ; DS:SI = String data + + 000D @@DP_Scan_it: + + 000D 80 3C 00 cmp b [SI], 0 ; Null Byte found? + 0010 74 04 je @@DP_Got_Len ; exit loop if so + + 0012 41 inc CX ; Len++ + 0013 46 inc SI ; Point to next char + 0014 EB F7 jmp s @@DP_Scan_it ; check again... + + 0016 @@DP_Got_len: + + 0016 E3 07 jcxz @No_Print ; Don't Print if empty + + 0018 BB 0001 mov BX, 1 ; 1= DOS Handle for Display + 001B B4 40 mov AH, 40h ; Write Text Function + 001D CD 21 int 21h ; Call DOS to do it + + 001F @No_Print: + 001F B8 ---- R mov AX, SEG DGROUP ; Restore DGroup + 0022 8E D8 mov DS, AX + + 0024 BA 0012 R mov DX, o CR_LF ; Get Addr of CR/LF pair + 0027 B9 0002 mov CX, 2 ; 2 Characters to Write + 002A BB 0001 mov BX, 1 ; 1= DOS Handle for Display + + 002D B4 40 mov AH, 40h ; Write Text Function + 002F CD 21 int 21h ; Call DOS to do it + + 0031 FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 0032 5F 1 pop DI ; Restore R1 + 0033 5E 2 pop SI ; Restore R1 + 0034 1F 3 pop DS ; Restore R1 + 0035 5D 4 pop BP ; Restore R1 + 0036 CA 0004 ret 4 ; Exit & Clean Up Stack + + 0039 DOS_PRINT ENDP + + + ;=========================================== + ;void far pascal dos_prints (char far *Text) + ;=========================================== + ; + ; Print Text Directly to DOS console + ; without a trailing CR/LF + ; + + PUBLIC DOS_PRINTS + + 0039 DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0039 55 1 push BP ; Save R1 + 003A 1E 2 push DS ; Save R1 + 003B 56 3 push SI ; Save R1 + 003C 57 4 push DI ; Save R1 + 003D 8B EC mov BP, SP ; Set up Stack Frame + + 003F C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor + + ; Compute Length of string + + CLR CX ; Length = 0 + 0042 33 C9 1 xor CX, CX ; Set Register = 0 + 0044 8B F2 mov SI, DX ; DS:SI = String data + + 0046 @@DPS_Scan_it: + + 0046 80 3C 00 cmp b [SI], 0 ; Null Byte found? + 0049 74 04 je @@DPS_Got_Len ; exit loop if so + + 004B 41 inc CX ; Len++ + 004C 46 inc SI ; Point to next char + 004D EB F7 jmp s @@DPS_Scan_it ; check again... + + 004F @@DPS_Got_len: + + 004F E3 07 jcxz @DPS_Exit ; Don't Print if empty + + 0051 BB 0001 mov BX, 1 ; 1= DOS Handle for Display + 0054 B4 40 mov AH, 40h ; Write Text Function + 0056 CD 21 int 21h ; Call DOS to do it + + 0058 @DPS_Exit: + 0058 FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 0059 5F 1 pop DI ; Restore R1 + 005A 5E 2 pop SI ; Restore R1 + 005B 1F 3 pop DS ; Restore R1 + 005C 5D 4 pop BP ; Restore R1 + 005D CA 0002 ret 2 ; Exit & Clean Up Stack + + 0060 DOS_PRINTS ENDP + + + ;========================================= + ;void far pascal set_video_mode (int Mode) + ;========================================= + ; + ; Sets the Video Mode through the BIOS + ; + + PUBLIC SET_VIDEO_MODE + + 000E SVM_Stack STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 00 00 SVM_Mode DB ?,? ; Desired Video Mode + SVM_Stack ENDS + + + 0060 SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0060 55 1 push BP ; Save R1 + 0061 1E 2 push DS ; Save R1 + 0062 56 3 push SI ; Save R1 + 0063 57 4 push DI ; Save R1 + 0064 8B EC mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + 0066 32 E4 1 xor AH, AH ; Set Register = 0 + 0068 8A 46 0C mov AL, [BP].SVM_Mode ; Get Mode # + + 006B CD 10 int 10H ; Change Video Modes + + 006D @SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + 006D 5F 1 pop DI ; Restore R1 + 006E 5E 2 pop SI ; Restore R1 + 006F 1F 3 pop DS ; Restore R1 + 0070 5D 4 pop BP ; Restore R1 + 0071 CA 0002 ret 2 ; Exit & Clean Up Stack + + 0074 SET_VIDEO_MODE ENDP + + + ;=================================== + ;int far pascal scan_keyboard (void) + ;=================================== + ; + ; Function to scan keyboard for a pressed key + ; + + PUBLIC SCAN_KEYBOARD + + 0074 SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0074 55 1 push BP ; Save R1 + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Page 2 - 1 + + + 0075 1E 2 push DS ; Save R1 + 0076 56 3 push SI ; Save R1 + 0077 57 4 push DI ; Save R1 + + 0078 B4 01 mov AH, 01H ; Function #1 + 007A CD 16 INT 16H ; Call Keyboard Driver + 007C 74 0C JZ @SK_NO_KEY ; Exit if Zero flag set + + 007E B4 00 mov AH, 00H ; Remove Key from Buffer + 0080 CD 16 INT 16H ; Get Keycode in AX + + 0082 0A C0 OR AL, AL ; Low Byte Set (Ascii?) + 0084 74 06 JZ @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + 0086 32 E4 1 xor AH, AH ; Set Register = 0 + 0088 EB 02 JMP s @SK_Exit ; Return Key in AX + + 008A @SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + 008A 33 C0 1 xor AX, AX ; Set Register = 0 + + 008C @SK_Exit: + 008C FC cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + 008D 5F 1 pop DI ; Restore R1 + 008E 5E 2 pop SI ; Restore R1 + 008F 1F 3 pop DS ; Restore R1 + 0090 5D 4 pop BP ; Restore R1 + 0091 CB ret ; Exit & Clean Up Stack + + 0092 SCAN_KEYBOARD ENDP + + + ;======================================== + ;int far pascal random_int (int MaxValue) + ;======================================== + ; + ; Returns a pseudo-random number in the range of (0.. MaxInt-1) + ; + + + PUBLIC RANDOM_INT + + 0008 RI_Stack STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 RI_MaxVal DW ? ; Maximum Value to Return + 1 + RI_Stack ENDS + + + 0092 RANDOM_INT PROC FAR + + 0092 55 push BP ; Preserve Important Registers + 0093 8B EC mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + 0095 33 DB 1 xor BX, BX ; Set Register = 0 + CLR CX ; CX is the accumulator + 0097 33 C9 1 xor CX, CX ; Set Register = 0 + + REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values + ENDM + 0099 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 009D F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00A1 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00A5 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00A9 03 CA 1 add CX, DX ; add it into the accumulator + 00AB 43 1 inc BX + 00AC 43 1 inc BX ; point to the next set of values + 00AD 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 00B1 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00B5 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00B9 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00BD 03 CA 1 add CX, DX ; add it into the accumulator + 00BF 43 1 inc BX + 00C0 43 1 inc BX ; point to the next set of values + 00C1 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed + 00C5 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it + 00C9 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value + 00CD 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time + 00D1 03 CA 1 add CX, DX ; add it into the accumulator + 00D3 43 1 inc BX + 00D4 43 1 inc BX ; point to the next set of values + + 00D5 8B C1 mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + 00D7 33 D2 1 xor DX, DX ; Set Register = 0 + 00D9 F7 76 06 div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + 00DC 8B C2 mov AX, DX + + 00DE 5D pop BP ; Restore BP + 00DF CA 0002 ret 2 ; back to BASIC with AX holding the result + + 00E2 RANDOM_INT ENDP + + + ;================================== + ;void far pascal init_random (void) + ;================================== + ; + ; Scrambles the psuedo-random number sequence + ; (XOR's the seed value with the timer) + ; + + PUBLIC INIT_RANDOM + + 00E2 INIT_RANDOM PROC FAR + + CLR AX ; Segment = 0000 + 00E2 33 C0 1 xor AX, AX ; Set Register = 0 + 00E4 8E C0 mov ES, AX + 00E6 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word + + 00EA 31 06 0000 R xor RND_Seed, AX ; Scramble 1st Seed + + 00EE CB ret ; Exit & Clean Up Stack + + 00EF INIT_RANDOM ENDP + + ;========================================= + ;int far pascal int_sqr (int X, int Round) + ;========================================= + ; + ; Returns the Integer Square Root of (X) + ; Round allows the return value to be rounded to the + ; nearest integer value by passing 0x80. Passing 0 + ; return the Integer Portion only. The rounding amound is + ; a number from 0 to 1 multiplied by 256, thus + ; 0.5 * 0x100 = 0x80! + ; + + 000C ISQ_Stack STRUC + 0000 0000 0000 DW ?,? ; BP, DI + 0004 00000000 DD ? ; Caller + 0008 0000 ISQ_Round DW ? ; Amount to Round Result * 256 + 000A 0000 ISQ_X DW ? ; "X" + ISQ_Stack ENDS + + PUBLIC INT_SQR + + 00EF INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + 00EF 55 1 push BP ; Save R1 + 00F0 57 2 push DI ; Save R1 + 00F1 8B EC mov BP, SP ; Set up Stack Frame + + 00F3 33 C0 xor AX, AX ; {xor eax,eax} + 00F5 33 D2 xor DX, DX ; {xor edx,edx} + 00F7 8B 7E 0A mov DI, [BP].ISQ_X ; {mov edi,x} + + 00FA B9 0010 mov CX, 16 ; {mov cx, 32} + + 00FD @ISQ_L: + + 00FD D1 E7 shl DI, 1 ; {shl edi,1} + 00FF D1 D2 rcl DX, 1 ; {rcl edx,1} + 0101 D1 E7 shl DI, 1 ; {shl edi,1} + 0103 D1 D2 rcl DX, 1 ; {rcl edx,1} + 0105 D1 E0 shl AX, 1 ; {shl eax,1} + 0107 8B D8 mov BX, AX ; {mov ebx,eax} + 0109 D1 E3 shl BX, 1 ; {shl ebx,1} + 010B 43 inc BX ; {inc ebx} + 010C 3B D3 cmp DX, BX ; {cmp edx,ebx} + 010E 7C 03 jl @ISQ_S + + 0110 2B D3 sub DX, BX ; {sub edx,ebx} + 0112 40 inc AX ; {inc eax} + + 0113 @ISQ_S: + 0113 E2 E8 loop @ISQ_L + + 0115 03 46 08 add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0 + .5} + 0118 C1 E8 08 shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + 011B 5F 1 pop DI ; Restore R1 + 011C 5D 2 pop BP ; Restore R1 + 011D CA 0004 ret 4 ; Exit + + 0120 INT_SQR ENDP + + ;================================= + ;int far pascal timer_count (void) + ;================================= + ; + ; Returns the current timer value as an integer/long integer + ; + + PUBLIC TIMER_COUNT + + 0120 TIMER_COUNT PROC FAR + + CLR AX ; Segment = 0000 + 0120 33 C0 1 xor AX, AX ; Set Register = 0 + 0122 8E C0 mov ES, AX + 0124 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word + 0128 26: 8B 16 046E mov DX, ES:[046Eh] ; Get Timer Hi Word + 012D CB ret ; Exit & Clean Up Stack + + 012E TIMER_COUNT ENDP + + + END + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 3 - 1 + + + + +Macros: + + N a m e Type + +CLR . . . . . . . . . . . . . . Proc +LOOPjz . . . . . . . . . . . . . Proc +LOOPx . . . . . . . . . . . . . Proc +POPx . . . . . . . . . . . . . . Proc +PUSHx . . . . . . . . . . . . . Proc + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 4 - 1 + + + + +Structures and Unions: + + N a m e Size + Offset Type + +DP_Stack . . . . . . . . . . . . 0010 + DP_Text . . . . . . . . . . . 000C DWord +ISQ_Stack . . . . . . . . . . . 000C + ISQ_Round . . . . . . . . . . 0008 Word + ISQ_X . . . . . . . . . . . . 000A Word +RI_Stack . . . . . . . . . . . . 0008 + RI_MaxVal . . . . . . . . . . 0006 Word +SVM_Stack . . . . . . . . . . . 000E + SVM_Mode . . . . . . . . . . . 000C Byte + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 5 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +C_UTILS_TEXT . . . . . . . . . . 16 Bit 012E Word Public 'CODE' +DGROUP . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 16 Bit 0014 Word Public 'DATA' + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 6 - 1 + + + + +Procedures, parameters and locals: + + N a m e Type Value Attr + +DOS_PRINTS . . . . . . . . . . . P Far 0039 C_UTILS_TEXT Length= 0027 Public +DOS_PRINT . . . . . . . . . . . P Far 0000 C_UTILS_TEXT Length= 0039 Public +INIT_RANDOM . . . . . . . . . . P Far 00E2 C_UTILS_TEXT Length= 000D Public +INT_SQR . . . . . . . . . . . . P Far 00EF C_UTILS_TEXT Length= 0031 Public +RANDOM_INT . . . . . . . . . . . P Far 0092 C_UTILS_TEXT Length= 0050 Public +SCAN_KEYBOARD . . . . . . . . . P Far 0074 C_UTILS_TEXT Length= 001E Public +SET_VIDEO_MODE . . . . . . . . . P Far 0060 C_UTILS_TEXT Length= 0014 Public +TIMER_COUNT . . . . . . . . . . P Far 0120 C_UTILS_TEXT Length= 000E Public + Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18 +c_utils.asm Symbols 7 - 1 + + + + +Symbols: + + N a m e Type Value Attr + +?x3 . . . . . . . . . . . . . . Text ?,?,? +?x4 . . . . . . . . . . . . . . Text ?,?,?,? +@@DPS_Got_len . . . . . . . . . L Near 004F C_UTILS_TEXT +@@DPS_Scan_it . . . . . . . . . L Near 0046 C_UTILS_TEXT +@@DP_Got_len . . . . . . . . . . L Near 0016 C_UTILS_TEXT +@@DP_Scan_it . . . . . . . . . . L Near 000D C_UTILS_TEXT +@CodeSize . . . . . . . . . . . Number 0001h +@DPS_Exit . . . . . . . . . . . L Near 0058 C_UTILS_TEXT +@DataSize . . . . . . . . . . . Number 0000h +@ISQ_L . . . . . . . . . . . . . L Near 00FD C_UTILS_TEXT +@ISQ_S . . . . . . . . . . . . . L Near 0113 C_UTILS_TEXT +@Interface . . . . . . . . . . . Number 0000h +@Model . . . . . . . . . . . . . Number 0004h +@No_Print . . . . . . . . . . . L Near 001F C_UTILS_TEXT +@SK_Exit . . . . . . . . . . . . L Near 008C C_UTILS_TEXT +@SK_NO_KEY . . . . . . . . . . . L Near 008A C_UTILS_TEXT +@SVM_Exit . . . . . . . . . . . L Near 006D C_UTILS_TEXT +@code . . . . . . . . . . . . . Text C_UTILS_TEXT +@data . . . . . . . . . . . . . Text DGROUP +@fardata? . . . . . . . . . . . Text FAR_BSS +@fardata . . . . . . . . . . . . Text FAR_DATA +@stack . . . . . . . . . . . . . Text DGROUP +CR_LF . . . . . . . . . . . . . Byte 0012 _DATA +False . . . . . . . . . . . . . Number 0000h +RND_ModV . . . . . . . . . . . . Word 000C _DATA +RND_Mult . . . . . . . . . . . . Word 0006 _DATA +RND_Seed . . . . . . . . . . . . Word 0000 _DATA +True . . . . . . . . . . . . . . Number -0001h +b . . . . . . . . . . . . . . . Text BYTE PTR +d . . . . . . . . . . . . . . . Text DWORD PTR +f . . . . . . . . . . . . . . . Text FAR PTR +nil . . . . . . . . . . . . . . Number 0000h +o . . . . . . . . . . . . . . . Text OFFSET +s . . . . . . . . . . . . . . . Text SHORT +w . . . . . . . . . . . . . . . Text WORD PTR + + 0 Warnings + 0 Errors diff --git a/src/lib/modex/demos/c/c_utils.sbr b/src/lib/modex/demos/c/c_utils.sbr new file mode 100755 index 00000000..0301171b Binary files /dev/null and b/src/lib/modex/demos/c/c_utils.sbr differ diff --git a/src/lib/modex/demos/c/makefile b/src/lib/modex/demos/c/makefile new file mode 100755 index 00000000..2c94d9bc --- /dev/null +++ b/src/lib/modex/demos/c/makefile @@ -0,0 +1,30 @@ +!ifdef __LINUX__ +REMOVECOMMAND=rm -f +COPYCOMMAND=cp -f +DIRSEP=/ +OBJ=o +!else +REMOVECOMMAND=del +COPYCOMMAND=copy /y +DIRSEP=\ +OBJ=obj +!endif + +CFLAGS=-d2 -0 -mc + +all: x-demo.exe + +x-demo.exe: x-demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ) + wcl $(CFLAGS) x-demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ) +x-demo.$(OBJ): x-demo.c + wcl -c $(CFLAGS) x-demo.c + +c_utils.$(OBJ): c_utils.asm + wcl -c $(CFLAGS) c_utils.asm +modex.$(OBJ): modex.asm + wcl -c $(CFLAGS) modex.asm + +clean: .symbolic + @$(REMOVECOMMAND) x-demo.exe + @$(REMOVECOMMAND) *.$(OBJ) + @$(REMOVECOMMAND) *.err diff --git a/src/lib/modex/demos/c/modex.asm b/src/lib/modex/demos/c/modex.asm new file mode 100755 index 00000000..f2b1b512 --- /dev/null +++ b/src/lib/modex/demos/c/modex.asm @@ -0,0 +1,3505 @@ +;======================================================== +; MODEX.ASM - A Complete Mode X Library +; +; Version 1.04 Release, 3 May 1993, By Matt Pritchard +; With considerable input from Michael Abrash +; +; The following information is donated to the public domain in +; the hopes that save other programmers much frustration. +; +; If you do use this code in a product, it would be nice if +; you include a line like "Mode X routines by Matt Pritchard" +; in the credits. +; +; ========================================================= +; +; All of this code is designed to be assembled with MASM 5.10a +; but TASM 3.0 could be used as well. +; +; The routines contained are designed for use in a MEDIUM model +; program. All Routines are FAR, and is assumed that a DGROUP +; data segment exists and that DS will point to it on entry. +; +; For all routines, the AX, BX, CX, DX, ES and FLAGS registers +; will not be preserved, while the DS, BP, SI and DI registers +; will be preserved. +; +; Unless specifically noted, All Parameters are assumed to be +; "PASSED BY VALUE". That is, the actual value is placed on +; the stack. When a reference is passed it is assumed to be +; a near pointer to a variable in the DGROUP segment. +; +; Routines that return a single 16-Bit integer value will +; return that value in the AX register. +; +; This code will *NOT* run on an 8086/8088 because 80286+ +; specific instructions are used. If you have an 8088/86 +; and VGA, you can buy an 80386-40 motherboard for about +; $160 and move into the 90's. +; +; This code is reasonably optimized: Most drawing loops have +; been unrolled once and memory references are minimized by +; keeping stuff in registers when possible. +; +; Error Trapping varies by Routine. No Clipping is performed +; so the caller should verify that all coordinates are valid. +; +; Several Macros are used to simplify common 2 or 3 instruction +; sequences. Several Single letter Text Constants also +; simplify common assembler expressions like "WORD PTR". +; +; ------------------ Mode X Variations ------------------ +; +; Mode # Screen Size Max Pages Aspect Ratio (X:Y) +; +; 0 320 x 200 4 Pages 1.2:1 +; 1 320 x 400 2 Pages 2.4:1 +; 2 360 x 200 3 Pages 1.35:1 +; 3 360 x 400 1 Page 2.7:1 +; 4 320 x 240 3 Pages 1:1 +; 5 320 x 480 1 Page 2:1 +; 6 360 x 240 3 Pages 1.125:1 +; 7 360 x 480 1 Page 2.25:1 +; +; -------------------- The Legal Stuff ------------------ +; +; No warranty, either written or implied, is made as to +; the accuracy and usability of this code product. Use +; at your own risk. Batteries not included. Pepperoni +; and extra cheese available for an additional charge. +; +; ----------------------- The Author -------------------- +; +; Matt Pritchard is a paid programmer who'd rather be +; writing games. He can be reached at: P.O. Box 140264, +; Irving, TX 75014 USA. Michael Abrash is a living +; god, who now works for Bill Gates (Microsoft). +; +; -------------------- Revision History ----------------- +; 4-12-93: v1.02 - SET_POINT & READ_POINT now saves DI +; SET_MODEX now saves SI +; 5-3-93: v1.04 - added LOAD_DAC_REGISTERS and +; READ_DAC_REGISTERS. Expanded CLR Macro +; to handle multiple registers +; + + PAGE 255, 132 + + .MODEL Huge + ;.286 + + ; ===== MACROS ===== + + ; Macro to OUT a 16 bit value to an I/O port + +OUT_16 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AX not setup + MOV AX, Value ; then Get Data Value + ENDIF + OUT DX, AX ; Set I/O Register(s) +ENDM + + ; Macro to OUT a 8 bit value to an I/O Port + +OUT_8 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AL not Setup + MOV AL, Value ; then Get Data Value + ENDIF + OUT DX, AL ; Set I/O Register +ENDM + + ; macros to PUSH and POP multiple registers + +; PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 +; IFNB +; PUSH R1 ; Save R1 +; PUSHx R2, R3, R4, R5, R6, R7, R8 +; ENDIF +; ENDM +; +; POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 +; IFNB +; POP R1 ; Restore R1 +; POPx R2, R3, R4, R5, R6, R7, R8 +; ENDIF +; ENDM + + ; Macro to Clear Registers to 0 + +; CLR MACRO Register, R2, R3, R4;, R5, R6 +; IFNB +; XOR Register, Register ; Set Register = 0 +; CLR R2, R3, R4;, R5, R6 +; ENDIF +; ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + DEC Register ; Counter-- + JNZ Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + DEC Register ; Counter-- + JZ Destination ; Jump if 0 +ENDM + + + ; ===== General Constants ===== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x1 EQU + + ; ===== VGA Register Values ===== + + VGA_Segment EQU 0A000h ; Vga Memory Segment + + ATTRIB_Ctrl EQU 03C0h ; VGA Attribute Controller + GC_Index EQU 03CEh ; VGA Graphics Controller + SC_Index EQU 03C4h ; VGA Sequencer Controller + SC_Data EQU 03C5h ; VGA Sequencer Data Port + CRTC_Index EQU 03D4h ; VGA CRT Controller + CRTC_Data EQU 03D5h ; VGA CRT Controller Data + MISC_OUTPUT EQU 03C2h ; VGA Misc Register + INPUT_1 EQU 03DAh ; Input Status #1 Register + + DAC_WRITE_ADDR EQU 03C8h ; VGA DAC Write Addr Register + DAC_READ_ADDR EQU 03C7h ; VGA DAC Read Addr Register + PEL_DATA_REG EQU 03C9h ; VGA DAC/PEL data Register R/W + + PIXEL_PAN_REG EQU 033h ; Attrib Index: Pixel Pan Reg + MAP_MASK EQU 002h ; Sequ Index: Write Map Mask reg + READ_MAP EQU 004h ; GC Index: Read Map Register + START_DISP_HI EQU 00Ch ; CRTC Index: Display Start Hi + START_DISP_LO EQU 00Dh ; CRTC Index: Display Start Lo + + MAP_MASK_PLANE1 EQU 00102h ; Map Register + Plane 1 + MAP_MASK_PLANE2 EQU 01102h ; Map Register + Plane 1 + ALL_PLANES_ON EQU 00F02h ; Map Register + All Bit Planes + + CHAIN4_OFF EQU 00604h ; Chain 4 mode Off + ASYNC_RESET EQU 00100h ; (A)synchronous Reset + SEQU_RESTART EQU 00300h ; Sequencer Restart + + LATCHES_ON EQU 00008h ; Bit Mask + Data from Latches + LATCHES_OFF EQU 0FF08h ; Bit Mask + Data from CPU + + VERT_RETRACE EQU 08h ; INPUT_1: Vertical Retrace Bit + PLANE_BITS EQU 03h ; Bits 0-1 of Xpos = Plane # + ALL_PLANES EQU 0Fh ; All Bit Planes Selected + CHAR_BITS EQU 0Fh ; Bits 0-3 of Character Data + + GET_CHAR_PTR EQU 01130h ; VGA BIOS Func: Get Char Set + ROM_8x8_Lo EQU 03h ; ROM 8x8 Char Set Lo Pointer + ROM_8x8_Hi EQU 04h ; ROM 8x8 Char Set Hi Pointer + + ; Constants Specific for these routines + + NUM_MODES EQU 8 ; # of Mode X Variations + + ; Specific Mode Data Table format... + +Mode_Data_Table STRUC + M_MiscR DB ? ; Value of MISC_OUTPUT register + M_Pages DB ? ; Maximum Possible # of pages + M_XSize DW ? ; X Size Displayed on screen + M_YSize DW ? ; Y Size Displayed on screen + M_XMax DW ? ; Maximum Possible X Size + M_YMax DW ? ; Maximum Possible Y Size + M_CRTC DW ? ; Table of CRTC register values +Mode_Data_Table ENDS + + ; ===== DGROUP STORAGE NEEDED (42 BYTES) ===== + + .DATA? + +SCREEN_WIDTH DW 0 ; Width of a line in Bytes +SCREEN_HEIGHT DW 0 ; Vertical Height in Pixels + +LAST_PAGE DW 0 ; # of Display Pages +PAGE_ADDR DW 4 DUP (0) ; Offsets to start of each page + +PAGE_SIZE DW 0 ; Size of Page in Addr Bytes + +DISPLAY_PAGE DW 0 ; Page # currently displayed +ACTIVE_PAGE DW 0 ; Page # currently active + +CURRENT_PAGE DW 0 ; Offset of current Page +CURRENT_SEGMENT DW 0 ; Segment of VGA memory + +CURRENT_XOFFSET DW 0 ; Current Display X Offset +CURRENT_YOFFSET DW 0 ; Current Display Y Offset + +CURRENT_MOFFSET DW 0 ; Current Start Offset + +MAX_XOFFSET DW 0 ; Current Display X Offset +MAX_YOFFSET DW 0 ; Current Display Y Offset + +CHARSET_LOW DW 0, 0 ; Far Ptr to Char Set: 0-127 +CHARSET_HI DW 0, 0 ; Far Ptr to Char Set: 128-255 + + .CODE + + ; ===== DATA TABLES ===== + + ; Data Tables, Put in Code Segment for Easy Access + ; (Like when all the other Segment Registers are in + ; use!!) and reduced DGROUP requirements... + + ; Bit Mask Tables for Left/Right/Character Masks + +Left_Clip_Mask DB 0FH, 0EH, 0CH, 08H + +Right_Clip_Mask DB 01H, 03H, 07H, 0FH + + ; Bit Patterns for converting character fonts + +Char_Plane_Data DB 00H,08H,04H,0CH,02H,0AH,06H,0EH + DB 01H,09H,05H,0DH,03H,0BH,07H,0FH + + ; CRTC Register Values for Various Configurations + +MODE_Single_Line: ; CRTC Setup Data for 400/480 Line modes + DW 04009H ; Cell Height (1 Scan Line) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 400/480 Line Mode + +MODE_Double_Line: ; CRTC Setup Data for 200/240 Line modes + DW 04109H ; Cell Height (2 Scan Lines) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 200/240 Line Mode + +MODE_320_Wide: ; CRTC Setup Data for 320 Horz Pixels + DW 05F00H ; Horz total + DW 04F01H ; Horz Displayed + DW 05002H ; Start Horz Blanking + DW 08203H ; End Horz Blanking + DW 05404H ; Start H Sync + DW 08005H ; End H Sync + DW nil ; End of CRTC Data for 320 Horz pixels + +MODE_360_Wide: ; CRTC Setup Data for 360 Horz Pixels + DW 06B00H ; Horz total + DW 05901H ; Horz Displayed + DW 05A02H ; Start Horz Blanking + DW 08E03H ; End Horz Blanking + DW 05E04H ; Start H Sync + DW 08A05H ; End H Sync + DW nil ; End of CRTC Data for 360 Horz pixels + +MODE_200_Tall: +MODE_400_Tall: ; CRTC Setup Data for 200/400 Line modes + DW 0BF06H ; Vertical Total + DW 01F07H ; Overflow + DW 09C10H ; V Sync Start + DW 08E11H ; V Sync End/Prot Cr0 Cr7 + DW 08F12H ; Vertical Displayed + DW 09615H ; V Blank Start + DW 0B916H ; V Blank End + DW nil ; End of CRTC Data for 200/400 Lines + +MODE_240_Tall: +MODE_480_Tall: ; CRTC Setup Data for 240/480 Line modes + DW 00D06H ; Vertical Total + DW 03E07H ; Overflow + DW 0EA10H ; V Sync Start + DW 08C11H ; V Sync End/Prot Cr0 Cr7 + DW 0DF12H ; Vertical Displayed + DW 0E715H ; V Blank Start + DW 00616H ; V Blank End + DW nil ; End of CRTC Data for 240/480 Lines + + ; Table of Display Mode Tables + +MODE_TABLE: + DW o MODE_320x200, o MODE_320x400 + DW o MODE_360x200, o MODE_360x400 + DW o MODE_320x240, o MODE_320x480 + DW o MODE_360x240, o MODE_360x480 + + ; Table of Display Mode Components + +MODE_320x200: ; Data for 320 by 200 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 4 ; Maximum of 4 Pages + DW 320, 200 ; Displayed Pixels (X,Y) + DW 1302, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_320x400: ; Data for 320 by 400 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 2 ; Maximum of 2 Pages + DW 320, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_400_Tall + DW o MODE_Single_Line, nil + +MODE_360x240: ; Data for 360 by 240 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 240 ; Displayed Pixels X,Y + DW 1092, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_240_Tall + DW o MODE_Double_Line , nil + +MODE_360x480: ; Data for 360 by 480 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 360, 480 ; Displayed Pixels X,Y + DW 544, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_480_Tall + DW o MODE_Single_Line , nil + +MODE_320x240: ; Data for 320 by 240 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 320, 240 ; Displayed Pixels X,Y + DW 1088, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_240_Tall + DW o MODE_Double_Line, nil + +MODE_320x480: ; Data for 320 by 480 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 320, 480 ; Displayed Pixels X,Y + DW 540, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_WIDE, o MODE_480_Tall + DW o MODE_Single_Line, nil + +MODE_360x200: ; Data for 360 by 200 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 200 ; Displayed Pixels (X,Y) + DW 1302, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_360x400: ; Data for 360 by 400 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 1 ; Maximum of 1 Pages + DW 360, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_400_Tall + DW o MODE_Single_Line, nil + + + ; ===== MODE X SETUP ROUTINES ===== + +;====================================================== +;SET_VGA_MODEX% (ModeType%, MaxXPos%, MaxYpos%, Pages%) +;====================================================== +; +; Sets Up the specified version of Mode X. Allows for +; the setup of multiple video pages, and a virtual +; screen which can be larger than the displayed screen +; (which can then be scrolled a pixel at a time) +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; +; 0 = 320 x 200, 4 Pages max, 1.2:1 Aspect Ratio +; 1 = 320 x 400, 2 Pages max, 2.4:1 Aspect Ratio +; 2 = 360 x 200, 3 Pages max, 1.35:1 Aspect Ratio +; 3 = 360 x 400, 1 Page max, 2.7:1 Aspect Ratio +; 4 = 320 x 240, 3 Pages max, 1:1 Aspect Ratio +; 5 = 320 x 480, 1 Page max, 2:1 Aspect Ratio +; 6 = 360 x 240, 3 Pages max, 1.125:1 Aspect Ratio +; 7 = 360 x 480, 1 Page max, 2.25:1 Aspect Ratio +; +; MaxXpos = The Desired Virtual Screen Width +; MaxYpos = The Desired Virtual Screen Height +; Pages = The Desired # of Video Pages +; +; EXIT: AX = Success Flag: >0 = Failure / 0 = Success +; + +SVM_STACK STRUC + SVM_Table DW ? ; Offset of Mode Info Table + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Pages DW ? ; # of Screen Pages desired + SVM_Ysize DW ? ; Vertical Screen Size Desired + SVM_Xsize DW ? ; Horizontal Screen Size Desired + SVM_Mode DW ? ; Display Resolution Desired +SVM_STACK ENDS + + PUBLIC SET_VGA_MODEX + +SET_VGA_MODEX PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 2 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + ; Check Legality of Mode Request.... + + MOV BX, [BP].SVM_Mode ; Get Requested Mode # + CMP BX, NUM_MODES ; Is it 0..7? + JAE @SVM_BadModeSetup1 ; If Not, Error out + + SHL BX, 1 ; Scale BX + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + MOV [BP].SVM_Table, SI ; Save ptr for later use + + ; Check # of Requested Display Pages + + MOV CX, [BP].SVM_Pages ; Get # of Requested Pages + ;CLR CH ; Set Hi Word = 0! + mov ch,0 ; Set Hi Word = 0! + CMP CL, CS:[SI].M_Pages ; Check # Pages for mode + JA @SVM_BadModeSetup2 ; Report Error if too Many Pages + JCXZ @SVM_BadModeSetup3 ; Report Error if 0 Pages + + ; Check Validity of X Size + + AND [BP].SVM_XSize, 0FFF8h ; X size Mod 8 Must = 0 + + MOV AX, [BP].SVM_XSize ; Get Logical Screen Width + CMP AX, CS:[SI].M_XSize ; Check against Displayed X + JB @SVM_BadModeSetup4 ; Report Error if too small + CMP AX, CS:[SI].M_XMax ; Check against Max X + JA @SVM_BadModeSetup5 ; Report Error if too big + + ; Check Validity of Y Size + + MOV BX, [BP].SVM_YSize ; Get Logical Screen Height + CMP BX, CS:[SI].M_YSize ; Check against Displayed Y + JB @SVM_BadModeSetup6 ; Report Error if too small + CMP BX, CS:[SI].M_YMax ; Check against Max Y + JA @SVM_BadModeSetup7 ; Report Error if too big + + ; Enough memory to Fit it all? + + SHR AX, 1 ; # of Bytes:Line = XSize/4 + SHR AX, 1 ; # of Bytes:Line = XSize/4 + MUL CX ; AX = Bytes/Line * Pages + MUL BX ; DX:AX = Total VGA mem needed + JNO @SVM_Continue ; Exit if Total Size > 256K + + DEC DX ; Was it Exactly 256K??? + OR DX, AX ; (DX = 1, AX = 0000) + JZ @SVM_Continue ; if so, it's valid... + + jmp @SVM_Continue;0000 + +@SVM_BadModeSetup: + mov ax,8 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup1: + mov ax,1 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup2: + mov ax,2 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup3: + mov ax,3 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup4: + mov ax,4 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup5: + mov ax,5 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup6: + mov ax,6 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup7: + mov ax,7 ; Return Value = False + JMP @SVM_Exit ; Normal Exit + +@SVM_Continue: + + MOV AX, 13H ; Start with Mode 13H + INT 10H ; Let BIOS Set Mode + + OUT_16 SC_INDEX, CHAIN4_OFF ; Disable Chain 4 Mode + OUT_16 SC_INDEX, ASYNC_RESET ; (A)synchronous Reset + OUT_8 MISC_OUTPUT, CS:[SI].M_MiscR ; Set New Timing/Size + OUT_16 SC_INDEX, SEQU_RESTART ; Restart Sequencer ... + + OUT_8 CRTC_INDEX, 11H ; Select Vert Retrace End Register + INC DX ; Point to Data + IN AL, DX ; Get Value, Bit 7 = Protect + AND AL, 7FH ; Mask out Write Protect + OUT DX, AL ; And send it back + + MOV DX, CRTC_INDEX ; Vga Crtc Registers + ADD SI, M_CRTC ; SI -> CRTC Parameter Data + + ; Load Tables of CRTC Parameters from List of Tables + +@SVM_Setup_Table: + + MOV DI, CS:[SI] ; Get Pointer to CRTC Data Tbl + ADD SI, 2 ; Point to next Ptr Entry + OR DI, DI ; A nil Ptr means that we have + JZ @SVM_Set_Data ; finished CRTC programming + +@SVM_Setup_CRTC: + MOV AX, CS:[DI] ; Get CRTC Data from Table + ADD DI, 2 ; Advance Pointer + OR AX, AX ; At End of Data Table? + JZ @SVM_Setup_Table ; If so, Exit & get next Table + + OUT DX, AX ; Reprogram VGA CRTC reg + JMP s @SVM_Setup_CRTC ; Process Next Table Entry + + ; Initialize Page & Scroll info, DI = 0 + +@SVM_Set_Data: + MOV DISPLAY_PAGE, DI ; Display Page = 0 + MOV ACTIVE_PAGE, DI ; Active Page = 0 + MOV CURRENT_PAGE, DI ; Current Page (Offset) = 0 + MOV CURRENT_XOFFSET, DI ; Horz Scroll Index = 0 + MOV CURRENT_YOFFSET, DI ; Vert Scroll Index = 0 + MOV CURRENT_MOFFSET, DI ; Memory Scroll Index = 0 + + MOV AX, VGA_SEGMENT ; Segment for VGA memory + MOV CURRENT_SEGMENT, AX ; Save for Future LES's + + ; Set Logical Screen Width, X Scroll and Our Data + + MOV SI, [BP].SVM_Table ; Get Saved Ptr to Mode Info + MOV AX, [BP].SVM_Xsize ; Get Display Width + + MOV CX, AX ; CX = Logical Width + SUB CX, CS:[SI].M_XSize ; CX = Max X Scroll Value + MOV MAX_XOFFSET, CX ; Set Maximum X Scroll + + SHR AX, 1 ; Bytes = Pixels / 4 + SHR AX, 1 ; Bytes = Pixels / 4 + MOV SCREEN_WIDTH, AX ; Save Width in Pixels + + SHR AX, 1 ; Offset Value = Bytes / 2 + MOV AH, 13h ; CRTC Offset Register Index + XCHG AL, AH ; Switch format for OUT + OUT DX, AX ; Set VGA CRTC Offset Reg + + ; Setup Data table, Y Scroll, Misc for Other Routines + + MOV AX, [BP].SVM_Ysize ; Get Logical Screen Height + + MOV CX, AX ; CX = Logical Height + SUB BX, CS:[SI].M_YSize ; CX = Max Y Scroll Value + MOV MAX_YOFFSET, CX ; Set Maximum Y Scroll + + MOV SCREEN_HEIGHT, AX ; Save Height in Pixels + MUL SCREEN_WIDTH ; AX = Page Size in Bytes, + MOV PAGE_SIZE, AX ; Save Page Size + + MOV CX, [BP].SVM_Pages ; Get # of Pages + MOV LAST_PAGE, CX ; Save # of Pages + + mov bx,0 ; Page # = 0 + MOV DX, BX ; Page 0 Offset = 0 + +@SVM_Set_Pages: + + MOV PAGE_ADDR[BX], DX ; Set Page #(BX) Offset + ADD BX, 2 ; Page#++ + ADD DX, AX ; Compute Addr of Next Page + LOOPx CX, @SVM_Set_Pages ; Loop until all Pages Set + + ; Clear VGA Memory + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; -> Start of VGA memory + + mov ax,0 ; AX = 0 + CLD ; Block Xfer Forwards + MOV CX, 8000H ; 32K * 4 * 2 = 256K + REP STOSW ; Clear dat memory! + + ; Setup Font Pointers + + MOV BH, ROM_8x8_Lo ; Ask for 8x8 Font, 0-127 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_LOW, BP ; Save Char Set Offset + MOV CHARSET_LOW+2, ES ; Save Char Set Segment + + MOV BH, ROM_8x8_Hi ; Ask for 8x8 Font, 128-255 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_HI, BP ; Save Char Set Offset + MOV CHARSET_HI+2, ES ; Save Char Set Segment + + MOV AX, True ; Return Success Code + +@SVM_EXIT: + ADD SP, 2 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 8 ; Exit & Clean Up Stack + +SET_VGA_MODEX ENDP + + +;================== +;SET_MODEX% (Mode%) +;================== +; +; Quickie Mode Set - Sets Up Mode X to Default Configuration +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; (See SET_VGA_MODEX for list) +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +SM_STACK STRUC + DW ?,? ; BP, SI + DD ? ; Caller + SM_Mode DW ? ; Desired Screen Resolution +SM_STACK ENDS + + PUBLIC SET_MODEX + +SET_MODEX PROC FAR + + ;PUSHx BP, SI ; Preserve Important registers + push bp + push si + MOV BP, SP ; Set up Stack Frame + + mov ax,0 ; Assume Failure + MOV BX, [BP].SM_Mode ; Get Desired Mode # + CMP BX, NUM_MODES ; Is it a Valid Mode #? + JAE @SMX_Exit ; If Not, don't Bother + + PUSH BX ; Push Mode Parameter + + SHL BX, 1 ; Scale BX to word Index + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + + PUSH CS:[SI].M_XSize ; Push Default X Size + PUSH CS:[SI].M_Ysize ; Push Default Y size + MOV AL, CS:[SI].M_Pages ; Get Default # of Pages + mov ah,0 ; Hi Byte = 0 + PUSH AX ; Push # Pages + + CALL f SET_VGA_MODEX ; Set up Mode X! + +@SMX_Exit: + ;POPx SI, BP ; Restore Registers + pop si + pop bp + RET 2 ; Exit & Clean Up Stack + +SET_MODEX ENDP + + + ; ===== BASIC GRAPHICS PRIMITIVES ===== + +;============================ +;CLEAR_VGA_SCREEN (ColorNum%) +;============================ +; +; Clears the active display page +; +; ENTRY: ColorNum = Color Value to fill the page with +; +; EXIT: No meaningful values returned +; + +CVS_STACK STRUC + DW ?,? ; DI, BP + DD ? ; Caller + CVS_COLOR DB ?,? ; Color to Set Screen to +CVS_STACK ENDS + + PUBLIC CLEAR_VGA_SCREEN + +CLEAR_VGA_SCREEN PROC FAR + + ;PUSHx BP, DI ; Preserve Important Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AL, [BP].CVS_COLOR ; Get Color + MOV AH, AL ; Copy for Word Write + CLD ; Block fill Forwards + + MOV CX, PAGE_SIZE ; Get Size of Page + SHR CX, 1 ; Divide by 2 for Words + REP STOSW ; Block Fill VGA memory + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 2 ; Exit & Clean Up Stack + +CLEAR_VGA_SCREEN ENDP + + +;=================================== +;SET_POINT (Xpos%, Ypos%, ColorNum%) +;=================================== +; +; Plots a single Pixel on the active display page +; +; ENTRY: Xpos = X position to plot pixel at +; Ypos = Y position to plot pixel at +; ColorNum = Color to plot pixel with +; +; EXIT: No meaningful values returned +; + +SP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + SETP_Color DB ?,? ; Color of Point to Plot + SETP_Ypos DW ? ; Y pos of Point to Plot + SETP_Xpos DW ? ; X pos of Point to Plot +SP_STACK ENDS + + PUBLIC SET_POINT + +SET_POINT PROC FAR + + ;PUSHx BP, DI ; Preserve Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].SETP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].SETP_Xpos ; Get Xpos + MOV CX, BX ; Copy to extract Plane # from + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AX, MAP_MASK_PLANE1 ; Map Mask & Plane Select Register + AND CL, PLANE_BITS ; Get Plane Bits + SHL AH, CL ; Get Plane Select Value + OUT_16 SC_Index, AX ; Select Plane + + MOV AL,[BP].SETP_Color ; Get Pixel Color + MOV ES:[DI+BX], AL ; Draw Pixel + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 6 ; Exit and Clean up Stack + +SET_POINT ENDP + + +;========================== +;READ_POINT% (Xpos%, Ypos%) +;========================== +; +; Read the color of a pixel from the Active Display Page +; +; ENTRY: Xpos = X position of pixel to read +; Ypos = Y position of pixel to read +; +; EXIT: AX = Color of Pixel at (Xpos, Ypos) +; + +RP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + RP_Ypos DW ? ; Y pos of Point to Read + RP_Xpos DW ? ; X pos of Point to Read +RP_STACK ENDS + + PUBLIC READ_POINT + +READ_POINT PROC FAR + + ;PUSHx BP, DI ; Preserve Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].RP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].RP_Xpos ; Get Xpos + MOV CX, BX + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AL, READ_MAP ; GC Read Mask Register + MOV AH, CL ; Get Xpos + AND AH, PLANE_BITS ; & mask out Plane # + OUT_16 GC_INDEX, AX ; Select Plane to read in + + mov ah,0 ; Clear Return Value Hi byte + MOV AL, ES:[DI+BX] ; Get Color of Pixel + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 4 ; Exit and Clean up Stack + +READ_POINT ENDP + + +;====================================================== +;FILL_BLOCK (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;====================================================== +; +; Fills a rectangular block on the active display Page +; +; ENTRY: Xpos1 = Left X position of area to fill +; Ypos1 = Top Y position of area to fill +; Xpos2 = Right X position of area to fill +; Ypos2 = Bottom Y position of area to fill +; ColorNum = Color to fill area with +; +; EXIT: No meaningful values returned +; + +FB_STACK STRUC + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + FB_Color DB ?,? ; Fill Color + FB_Ypos2 DW ? ; Y pos of Lower Right Pixel + FB_Xpos2 DW ? ; X pos of Lower Right Pixel + FB_Ypos1 DW ? ; Y pos of Upper Left Pixel + FB_Xpos1 DW ? ; X pos of Upper Left Pixel +FB_STACK ENDS + + PUBLIC FILL_BLOCK + +FILL_BLOCK PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + + ; Validate Pixel Coordinates + ; If necessary, Swap so X1 <= X2, Y1 <= Y2 + + MOV AX, [BP].FB_Ypos1 ; AX = Y1 is Y1< Y2? + MOV BX, [BP].FB_Ypos2 ; BX = Y2 + CMP AX, BX + JLE @FB_NOSWAP1 + + MOV [BP].FB_Ypos1, BX ; Swap Y1 and Y2 and save Y1 + XCHG AX, BX ; on stack for future use + +@FB_NOSWAP1: + SUB BX, AX ; Get Y width + INC BX ; Add 1 to avoid 0 value + MOV [BP].FB_Ypos2, BX ; Save in Ypos2 + + MUL SCREEN_WIDTH ; Mul Y1 by Bytes per Line + ADD DI, AX ; DI = Start of Line Y1 + + MOV AX, [BP].FB_Xpos1 ; Check X1 <= X2 + MOV BX, [BP].FB_Xpos2 ; + CMP AX, BX + JLE @FB_NOSWAP2 ; Skip Ahead if Ok + + MOV [BP].FB_Xpos2, AX ; Swap X1 AND X2 and save X2 + XCHG AX, BX ; on stack for future use + + ; All our Input Values are in order, Now determine + ; How many full "bands" 4 pixels wide (aligned) there + ; are, and if there are partial bands (<4 pixels) on + ; the left and right edges. + +@FB_NOSWAP2: + MOV DX, AX ; DX = X1 (Pixel Position) + SHR DX, 1 ; DX/4 = Bytes into Line + SHR DX, 1 ; DX/4 = Bytes into Line + ADD DI, DX ; DI = Addr of Upper-Left Corner + + MOV CX, BX ; CX = X2 (Pixel Position) + SHR CX, 1 ; CX/4 = Bytes into Line + SHR CX, 1 ; CX/4 = Bytes into Line + + CMP DX, CX ; Start and end in same band? + JNE @FB_NORMAL ; if not, check for l & r edges + JMP @FB_ONE_BAND_ONLY ; if so, then special processing + +@FB_NORMAL: + SUB CX, DX ; CX = # bands -1 + MOV SI, AX ; SI = PLANE#(X1) + AND SI, PLANE_BITS ; if Left edge is aligned then + JZ @FB_L_PLANE_FLUSH ; no special processing.. + + ; Draw "Left Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Left_Clip_Mask[SI] ; Set Left Edge Plane Mask + + MOV SI, DI ; SI = Copy of Start Addr (UL) + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_LEFT_LOOP: + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_LEFT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_LEFT_LOOP ; loop until left strip is drawn + +@FB_LEFT_CONT: + + INC DI ; Point to Middle (or Right) Block + DEC CX ; Reset CX instead of JMP @FB_RIGHT + +@FB_L_PLANE_FLUSH: + INC CX ; Add in Left band to middle block + + ; DI = Addr of 1st middle Pixel (band) to fill + ; CX = # of Bands to fill -1 + +@FB_RIGHT: + MOV SI, [BP].FB_Xpos2 ; Get Xpos2 + AND SI, PLANE_BITS ; Get Plane values + CMP SI, 0003 ; Plane = 3? + JE @FB_R_EDGE_FLUSH ; Hey, add to middle + + ; Draw "Right Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Right_Clip_Mask[SI] ; Right Edge Plane Mask + + MOV SI, DI ; Get Addr of Left Edge + ADD SI, CX ; Add Width-1 (Bands) + DEC SI ; To point to top of Right Edge + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_RIGHT_LOOP: + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_RIGHT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_RIGHT_LOOP ; loop until left strip is drawn + +@FB_RIGHT_CONT: + + DEC CX ; Minus 1 for Middle bands + JZ @FB_EXIT ; Uh.. no Middle bands... + +@FB_R_EDGE_FLUSH: + + ; DI = Addr of Upper Left block to fill + ; CX = # of Bands to fill in (width) + + OUT_8 SC_Data, ALL_PLANES ; Write to All Planes + + MOV DX, SCREEN_WIDTH ; DX = DI Increment + SUB DX, CX ; = Screen_Width-# Planes Filled + + MOV BX, CX ; BX = Quick Refill for CX + MOV SI, [BP].FB_Ypos2 ; SI = # of Line to Fill + MOV AL, [BP].FB_Color ; Get Fill Color + +@FB_MIDDLE_LOOP: + REP STOSB ; Fill in entire line + + MOV CX, BX ; Recharge CX (Line Width) + ADD DI, DX ; Point to start of Next Line + LOOPx SI, @FB_MIDDLE_LOOP ; Loop until all lines drawn + + JMP s @FB_EXIT ; Outa here + +@FB_ONE_BAND_ONLY: + MOV SI, AX ; Get Left Clip Mask, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV SI, BX ; Get Right Clip Mask, Save X2 + AND SI, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[SI] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_ONE_LOOP: + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPjz CX, @FB_EXIT ; Exit loop if all Lines Drawn + + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPx CX, @FB_ONE_LOOP ; loop until left strip is drawn + +@FB_EXIT: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 10 ; Exit and Clean up Stack + +FILL_BLOCK ENDP + + +;===================================================== +;DRAW_LINE (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;===================================================== +; +; Draws a Line on the active display page +; +; ENTRY: Xpos1 = X position of first point on line +; Ypos1 = Y position of first point on line +; Xpos2 = X position of last point on line +; Ypos2 = Y position of last point on line +; ColorNum = Color to draw line with +; +; EXIT: No meaningful values returned +; + +DL_STACK STRUC + DW ?x1 ; DI, SI, BP + DW ?x1 ; DI, SI, BP + DW ?x1 ; DI, SI, BP + DD ? ; Caller + DL_ColorF DB ?,? ; Line Draw Color + DL_Ypos2 DW ? ; Y pos of last point + DL_Xpos2 DW ? ; X pos of last point + DL_Ypos1 DW ? ; Y pos of first point + DL_Xpos1 DW ? ; X pos of first point +DL_STACK ENDS + + PUBLIC DRAW_LINE + +DRAW_LINE PROC FAR + + ;PUSHx BP, SI, DI ; Preserve Important Registers + push bp + push si + push di + MOV BP, SP ; Set up Stack Frame + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + MOV CH, [BP].DL_ColorF ; Save Line Color in CH + + ; Check Line Type + + MOV SI, [BP].DL_Xpos1 ; AX = X1 is X1< X2? + MOV DI, [BP].DL_Xpos2 ; DX = X2 + CMP SI, DI ; Is X1 < X2 + JE @DL_VLINE ; If X1=X2, Draw Vertical Line + JL @DL_NOSWAP1 ; If X1 < X2, don't swap + + XCHG SI, DI ; X2 IS > X1, SO SWAP THEM + +@DL_NOSWAP1: + + ; SI = X1, DI = X2 + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 is Y1 <> Y2? + CMP AX, [BP].DL_Ypos2 ; Y1 = Y2? + JE @DL_HORZ ; If so, Draw a Horizontal Line + + JMP @DL_BREZHAM ; Diagonal line... go do it... + + ; This Code draws a Horizontal Line in Mode X where: + ; SI = X1, DI = X2, and AX = Y1/Y2 + +@DL_HORZ: + + MUL SCREEN_WIDTH ; Offset = Ypos * Screen_Width + MOV DX, AX ; CX = Line offset into Page + + MOV AX, SI ; Get Left edge, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV BL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV CX, DI ; Get Right edge, Save X2 + AND DI, PLANE_BITS ; Mask out Row # + MOV BH, Right_Clip_Mask[DI] ; Get Right Edge Mask byte + + SHR AX, 1 ; Get X1 Byte # (=X1/4) + SHR CX, 1 ; Get X2 Byte # (=X2/4) + SHR AX, 1 ; Get X1 Byte # (=X1/4) + SHR CX, 1 ; Get X2 Byte # (=X2/4) + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, DX ; Point to Start of Line + ADD DI, AX ; Point to Pixel X1 + + SUB CX, AX ; CX = # Of Bands (-1) to set + JNZ @DL_LONGLN ; jump if longer than one segment + + AND BL, BH ; otherwise, merge clip masks + +@DL_LONGLN: + + OUT_8 SC_Data, BL ; Set the Left Clip Mask + + MOV AL, [BP].DL_ColorF ; Get Line Color + MOV BL, AL ; BL = Copy of Line Color + STOSB ; Set Left (1-4) Pixels + + JCXZ @DL_EXIT ; Done if only one Line Segment + + DEC CX ; CX = # of Middle Segments + JZ @DL_XRSEG ; If no middle segments.... + + ; Draw Middle Segments + + OUT_8 DX, ALL_PLANES ; Write to ALL Planes + + MOV AL, BL ; Get Color from BL + REP STOSB ; Draw Middle (4 Pixel) Segments + +@DL_XRSEG: + OUT_8 DX, BH ; Select Planes for Right Clip Mask + MOV AL, BL ; Get Color Value + STOSB ; Draw Right (1-4) Pixels + + JMP s @DL_EXIT ; We Are Done... + + + ; This Code Draws A Vertical Line. On entry: + ; CH = Line Color, SI & DI = X1 + +@DL_VLINE: + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 + MOV SI, [BP].DL_Ypos2 ; SI = Y2 + CMP AX, SI ; Is Y1 < Y2? + JLE @DL_NOSWAP2 ; if so, Don't Swap them + + XCHG AX, SI ; Ok, NOW Y1 < Y2 + +@DL_NOSWAP2: + + SUB SI, AX ; SI = Line Height (Y2-Y1+1) + INC SI + + ; AX = Y1, DI = X1, Get offset into Page into AX + + MUL SCREEN_WIDTH ; Offset = Y1 (AX) * Screen Width + MOV DX, DI ; Copy Xpos into DX + SHR DI, 1 ; DI = Xpos/4 + SHR DI, 1 ; DI = Xpos/4 + ADD AX, DI ; DI = Xpos/4 + ScreenWidth * Y1 + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, AX ; Point to Pixel X1, Y1 + + ;Select Plane + + MOV CL, DL ; CL = Save X1 + AND CL, PLANE_BITS ; Get X1 MOD 4 (Plane #) + MOV AX, MAP_MASK_PLANE1 ; Code to set Plane #1 + SHL AH, CL ; Change to Correct Plane # + OUT_16 SC_Index, AX ; Select Plane + + MOV AL, CH ; Get Saved Color + MOV BX, SCREEN_WIDTH ; Get Offset to Advance Line By + +@DL_VLoop: + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPjz SI, @DL_EXIT ; Lines--, Exit if done + + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPx SI, @DL_VLoop ; Lines--, Loop until Done + +@DL_EXIT: + + JMP @DL_EXIT2 ; Done! + + ; This code Draws a diagonal line in Mode X + +@DL_BREZHAM: + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].DL_Ypos1 ; get Y1 value + MOV BX, [BP].DL_Ypos2 ; get Y2 value + MOV CX, [BP].DL_Xpos1 ; Get Starting Xpos + + CMP BX, AX ; Y2-Y1 is? + JNC @DL_DeltaYOK ; if Y2>=Y1 then goto... + + XCHG BX, AX ; Swap em... + MOV CX, [BP].DL_Xpos2 ; Get New Starting Xpos + +@DL_DeltaYOK: + MUL SCREEN_WIDTH ; Offset = SCREEN_WIDTH * Y1 + + ADD DI, AX ; DI -> Start of Line Y1 on Page + MOV AX, CX ; AX = Xpos (X1) + SHR AX, 1 ; /4 = Byte Offset into Line + SHR AX, 1 ; /4 = Byte Offset into Line + ADD DI, AX ; DI = Starting pos (X1,Y1) + + MOV AL, 11h ; Staring Mask + AND CL, PLANE_BITS ; Get Plane # + SHL AL, CL ; and shift into place + MOV AH, [BP].DL_ColorF ; Color in Hi Bytes + + PUSH AX ; Save Mask,Color... + + MOV AH, AL ; Plane # in AH + MOV AL, MAP_MASK ; Select Plane Register + OUT_16 SC_Index, AX ; Select initial plane + + MOV AX, [BP].DL_Xpos1 ; get X1 value + MOV BX, [BP].DL_Ypos1 ; get Y1 value + MOV CX, [BP].DL_Xpos2 ; get X2 value + MOV DX, [BP].DL_Ypos2 ; get Y2 value + + MOV BP, SCREEN_WIDTH ; Use BP for Line width to + ; to avoid extra memory access + + SUB DX, BX ; figure Delta_Y + JNC @DL_DeltaYOK2 ; jump if Y2 >= Y1 + + ADD BX, DX ; put Y2 into Y1 + NEG DX ; abs(Delta_Y) + XCHG AX, CX ; and exchange X1 and X2 + +@DL_DeltaYOK2: + MOV BX, 08000H ; seed for fraction accumulator + + SUB CX, AX ; figure Delta_X + JC @DL_DrawLeft ; if negative, go left + + JMP @DL_DrawRight ; Draw Line that slopes right + +@DL_DrawLeft: + + NEG CX ; abs(Delta_X) + + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepLeft ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the left in Mode X + +@DL_ShallowLeft: + mov ax,0 ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Left, and Maybe Down... + +@DL_SLLLoop: + MOV ES:[DI], AH ; set first pixel, plane data set up + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLLL2nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL2nc: + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator, + JNC @DL_SLLL3nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL3nc: ; Now move left a pixel... + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLLLoop ; loop until done + +@DL_SLLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a steep line to the left in Mode X + +@DL_SteepLeft: + mov ax,0 ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe left + +@DL_STLLoop: + + MOV ES:[DI], AH ; set first pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc2 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc3 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc3: + ADD DI, BP ; advance to next line. + JMP s @DL_STLLoop ; Loop until done + +@DL_STLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a line that goes to the Right... + +@DL_DrawRight: + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepRight ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the Right in Mode X + +@DL_ShallowRight: + mov ax,0 ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Right, and Maybe Down... + +@DL_SLRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR2nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR2nc: ; Now move right a pixel... + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR3nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR3nc: + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLRLoop ; loop till done + +@DL_SLRExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a Steep line to the Right in Mode X + +@DL_SteepRight: + mov ax,0 ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe Right + +@STRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc2 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc3 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc3: + ADD DI, BP ; advance to next line. + JMP s @STRLoop ; loop till done + +@DL_EXIT2: + ;POPx DI, SI, BP ; Restore Saved Registers + pop di + pop si + pop bp + RET 10 ; Exit and Clean up Stack + +DRAW_LINE ENDP + + + ; ===== DAC COLOR REGISTER ROUTINES ===== + +;================================================= +;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%) +;================================================= +; +; Sets a single (RGB) Vga Palette Register +; +; ENTRY: Register = The DAC # to modify (0-255) +; Red = The new Red Intensity (0-63) +; Green = The new Green Intensity (0-63) +; Blue = The new Blue Intensity (0-63) +; +; EXIT: No meaningful values returned +; + +SDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDR_Blue DB ?,? ; Blue Data Value + SDR_Green DB ?,? ; Green Data Value + SDR_Red DB ?,? ; Red Data Value + SDR_Register DB ?,? ; Palette Register # +SDR_STACK ENDS + + PUBLIC SET_DAC_REGISTER + +SET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to modify + + OUT_8 DAC_WRITE_ADDR, [BP].SDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + OUT_8 DX, [BP].SDR_Red ; Set Red Intensity + OUT_8 DX, [BP].SDR_Green ; Set Green Intensity + OUT_8 DX, [BP].SDR_Blue ; Set Blue Intensity + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +SET_DAC_REGISTER ENDP + +;==================================================== +;GET_DAC_REGISTER (Register%, &Red%, &Green%, &Blue%) +;==================================================== +; +; Reads the RGB Values of a single Vga Palette Register +; +; ENTRY: Register = The DAC # to read (0-255) +; Red = Offset to Red Variable in DS +; Green = Offset to Green Variable in DS +; Blue = Offset to Blue Variable in DS +; +; EXIT: The values of the integer variables Red, +; Green, and Blue are set to the values +; taken from the specified DAC register. +; + +GDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + GDR_Blue DW ? ; Addr of Blue Data Value in DS + GDR_Green DW ? ; Addr of Green Data Value in DS + GDR_Red DW ? ; Addr of Red Data Value in DS + GDR_Register DB ?,? ; Palette Register # +GDR_STACK ENDS + + PUBLIC GET_DAC_REGISTER + +GET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to read in + + OUT_8 DAC_READ_ADDR, [BP].GDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + mov ax,0 ; Clear AX + + IN AL, DX ; Read Red Value + MOV BX, [BP].GDR_Red ; Get Address of Red% + MOV [BX], AX ; *Red% = AX + + IN AL, DX ; Read Green Value + MOV BX, [BP].GDR_Green ; Get Address of Green% + MOV [BX], AX ; *Green% = AX + + IN AL, DX ; Read Blue Value + MOV BX, [BP].GDR_Blue ; Get Address of Blue% + MOV [BX], AX ; *Blue% = AX + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +GET_DAC_REGISTER ENDP + + +;=========================================================== +;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%) +;=========================================================== +; +; Sets a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to Block of palette data +; StartReg = First Register # in range to set (0-255) +; EndReg = Last Register # in Range to set (0-255) +; Sync = Wait for Vertical Retrace Flag (Boolean) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +LDR_STACK STRUC + DW ?x1 ; BP, DS, SI + DW ?x1 ; BP, DS, SI + DW ?x1 ; BP, DS, SI + DD ? ; Caller + LDR_Sync DW ? ; Vertical Sync Flag + LDR_EndReg DB ?,? ; Last Register # + LDR_StartReg DB ?,? ; First Register # + LDR_PalData DD ? ; Far Ptr to Palette Data +LDR_STACK ENDS + + PUBLIC LOAD_DAC_REGISTERS + +LOAD_DAC_REGISTERS PROC FAR + + ;PUSHx BP, DS, SI ; Save Registers + push bp + push ds + push si + mov BP, SP ; Set up Stack Frame + + mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag + or AX, AX ; is Sync Flag = 0? + jz @LDR_Load ; if so, skip call + + call f SYNC_DISPLAY ; wait for vsync + + ; Determine register #'s, size to copy, etc + +@LDR_Load: + + lds SI, [BP].LDR_PalData ; DS:SI -> Palette Data + mov DX, DAC_WRITE_ADDR ; DAC register # selector + + mov ax,0, BX ; Clear for byte loads + mov AL, [BP].LDR_StartReg ; Get Start Register + mov BL, [BP].LDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block OUTs forward + out DX, AL ; set up correct register # + + ; Load a block of DAC Registers + + mov DX, PEL_DATA_REG ; Dac Data Register + + ;rep outsb ; block set DAC registers + + ;POPx SI, DS, BP ; Restore Registers + pop si + pop ds + pop bp + ret 10 ; Exit & Clean Up Stack + +LOAD_DAC_REGISTERS ENDP + + +;==================================================== +;READ_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%) +;==================================================== +; +; Reads a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to block to store palette data +; StartReg = First Register # in range to read (0-255) +; EndReg = Last Register # in Range to read (0-255) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +RDR_STACK STRUC + DW ?x1 ; BP, ES, DI + DW ?x1 ; BP, ES, DI + DW ?x1 ; BP, ES, DI + DD ? ; Caller + RDR_EndReg DB ?,? ; Last Register # + RDR_StartReg DB ?,? ; First Register # + RDR_PalData DD ? ; Far Ptr to Palette Data +RDR_STACK ENDS + + PUBLIC READ_DAC_REGISTERS + +READ_DAC_REGISTERS PROC FAR + + ;PUSHx BP, ES, DI ; Save Registers + push bp + push es + push di + mov BP, SP ; Set up Stack Frame + + ; Determine register #'s, size to copy, etc + + les DI, [BP].RDR_PalData ; ES:DI -> Palette Buffer + mov DX, DAC_READ_ADDR ; DAC register # selector + + mov ax,0, BX ; Clear for byte loads + mov AL, [BP].RDR_StartReg ; Get Start Register + mov BL, [BP].RDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block INs forward + + ; Read a block of DAC Registers + + out DX, AL ; set up correct register # + mov DX, PEL_DATA_REG ; Dac Data Register + + ;rep insb ; block read DAC registers + + ;POPx DI, ES, BP ; Restore Registers + pop di + pop es + pop bp + ret 8 ; Exit & Clean Up Stack + +READ_DAC_REGISTERS ENDP + + + ; ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +;========================= +;SET_ACTIVE_PAGE (PageNo%) +;========================= +; +; Sets the active display Page to be used for future drawing +; +; ENTRY: PageNo = Display Page to make active +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SAP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SAP_Page DW ? ; Page # for Drawing +SAP_STACK ENDS + + PUBLIC SET_ACTIVE_PAGE + +SET_ACTIVE_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SAP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SAP_Exit ; IF Not, Do Nothing + + MOV ACTIVE_PAGE, BX ; Set Active Page # + + SHL BX, 1 ; Scale Page # to Word + MOV AX, PAGE_ADDR[BX] ; Get offset to Page + + MOV CURRENT_PAGE, AX ; And set for future LES's + +@SAP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_ACTIVE_PAGE ENDP + + +;================ +;GET_ACTIVE_PAGE% +;================ +; +; Returns the Video Page # currently used for Drawing +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page used for Drawing +; + + PUBLIC GET_ACTIVE_PAGE + +GET_ACTIVE_PAGE PROC FAR + + MOV AX, ACTIVE_PAGE ; Get Active Page # + RET ; Exit and Clean up Stack + +GET_ACTIVE_PAGE ENDP + + +;=============================== +;SET_DISPLAY_PAGE (DisplayPage%) +;=============================== +; +; Sets the currently visible display page. +; When called this routine syncronizes the display +; to the vertical blank. +; +; ENTRY: PageNo = Display Page to show on the screen +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SDP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDP_Page DW ? ; Page # to Display... +SDP_STACK ENDS + + PUBLIC SET_DISPLAY_PAGE + +SET_DISPLAY_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SDP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SDP_Exit ; IF Not, Do Nothing + + MOV DISPLAY_PAGE, BX ; Set Display Page # + + SHL BX, 1 ; Scale Page # to Word + MOV CX, PAGE_ADDR[BX] ; Get offset in memory to Page + ADD CX, CURRENT_MOFFSET ; Adjust for any scrolling + + ; Wait if we are currently in a Vertical Retrace + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @DP_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new page + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, CL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, CH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @DP_WAIT1 ; If Not, wait for it + + ; Now Set Display Starting Address + + +@SDP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_DISPLAY_PAGE ENDP + + +;================= +;GET_DISPLAY_PAGE% +;================= +; +; Returns the Video Page # currently displayed +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page being displayed +; + + PUBLIC GET_DISPLAY_PAGE + +GET_DISPLAY_PAGE PROC FAR + + MOV AX, DISPLAY_PAGE ; Get Display Page # + RET ; Exit & Clean Up Stack + +GET_DISPLAY_PAGE ENDP + + +;======================================= +;SET_WINDOW (DisplayPage%, Xpos%, Ypos%) +;======================================= +; +; Since a Logical Screen can be larger than the Physical +; Screen, Scrolling is possible. This routine sets the +; Upper Left Corner of the Screen to the specified Pixel. +; Also Sets the Display page to simplify combined page +; flipping and scrolling. When called this routine +; syncronizes the display to the vertical blank. +; +; ENTRY: DisplayPage = Display Page to show on the screen +; Xpos = # of pixels to shift screen right +; Ypos = # of lines to shift screen down +; +; EXIT: No meaningful values returned +; + +SW_STACK STRUC + DW ? ; BP + DD ? ; Caller + SW_Ypos DW ? ; Y pos of UL Screen Corner + SW_Xpos DW ? ; X pos of UL Screen Corner + SW_Page DW ? ; (new) Display Page +SW_STACK ENDS + + PUBLIC SET_WINDOW + +SET_WINDOW PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + ; Check if our Scroll Offsets are Valid + + MOV BX, [BP].SW_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SW_Exit ; IF Not, Do Nothing + + MOV AX, [BP].SW_Ypos ; Get Desired Y Offset + CMP AX, MAX_YOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + MOV CX, [BP].SW_Xpos ; Get Desired X Offset + CMP CX, MAX_XOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + ; Compute proper Display start address to use + + MUL SCREEN_WIDTH ; AX = YOffset * Line Width + SHR CX, 1 ; CX / 4 = Bytes into Line + SHR CX, 1 ; CX / 4 = Bytes into Line + ADD AX, CX ; AX = Offset of Upper Left Pixel + + MOV CURRENT_MOFFSET, AX ; Save Offset Info + + MOV DISPLAY_PAGE, BX ; Set Current Page # + SHL BX, 1 ; Scale Page # to Word + ADD AX, PAGE_ADDR[BX] ; Get offset in VGA to Page + MOV BX, AX ; BX = Desired Display Start + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait if we are currently in a Vertical Retrace + +@SW_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SW_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new window + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, BL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, BH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@SW_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SW_WAIT1 ; If Not, wait for it + + ; Now Set the Horizontal Pixel Pan values + + OUT_8 ATTRIB_Ctrl, PIXEL_PAN_REG ; Select Pixel Pan Register + + MOV AX, [BP].SW_Xpos ; Get Desired X Offset + AND AL, 03 ; Get # of Pixels to Pan (0-3) + SHL AL, 1 ; Shift for 256 Color Mode + OUT DX, AL ; Fine tune the display! + +@SW_Exit: + POP BP ; Restore Saved Registers + RET 6 ; Exit and Clean up Stack + +SET_WINDOW ENDP + + +;============= +;GET_X_OFFSET% +;============= +; +; Returns the X coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Horizontal Scroll Offset +; + + PUBLIC GET_X_OFFSET + +GET_X_OFFSET PROC FAR + + MOV AX, CURRENT_XOFFSET ; Get current horz offset + RET ; Exit & Clean Up Stack + +GET_X_OFFSET ENDP + + +;============= +;GET_Y_OFFSET% +;============= +; +; Returns the Y coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Vertical Scroll Offset +; + + PUBLIC GET_Y_OFFSET + +GET_Y_OFFSET PROC FAR + + MOV AX, CURRENT_YOFFSET ; Get current vertical offset + RET ; Exit & Clean Up Stack + +GET_Y_OFFSET ENDP + + +;============ +;SYNC_DISPLAY +;============ +; +; Pauses the computer until the next Vertical Retrace starts +; +; ENTRY: No Parameters are passed +; +; EXIT: No meaningful values returned +; + + PUBLIC SYNC_DISPLAY + +SYNC_DISPLAY PROC FAR + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait for any current retrace to end + +@SD_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SD_WAIT0 ; If Not, wait for it + + ; Wait for the start of the next vertical retrace + +@SD_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SD_WAIT1 ; If Not, wait for it + + RET ; Exit & Clean Up Stack + +SYNC_DISPLAY ENDP + + + ; ===== TEXT DISPLAY ROUTINES ===== + +;================================================== +;GPRINTC (CharNum%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================== +; +; Draws an ASCII Text Character using the currently selected +; 8x8 font on the active display page. It would be a simple +; exercise to make this routine process variable height fonts. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +GPC_STACK STRUC + GPC_Width DW ? ; Screen Width-1 + GPC_Lines DB ?,? ; Scan lines to Decode + GPC_T_SETS DW ? ; Saved Charset Segment + GPC_T_SETO DW ? ; Saved Charset Offset + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + GPC_ColorB DB ?,? ; Background Color + GPC_ColorF DB ?,? ; Text Color + GPC_Ypos DW ? ; Y Position to Print at + GPC_Xpos DW ? ; X position to Print at + GPC_Char DB ?,? ; Character to Print +GPC_STACK ENDS + + PUBLIC GPRINTC + +GPRINTC PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].GPC_Width, BX ; Save for later use + + MUL [BP].GPC_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].GPC_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 1 ; Bytes into Line = Xpos/4 + SHR AX, 1 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].GPC_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @GPC_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @GPC_Set_Char ; Go Setup Character Ptr + +@GPC_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@GPC_Set_Char: + MOV [BP].GPC_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].GPC_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].GPC_Lines, AL ; Save on Stack + + MOV DS, [BP].GPC_T_SETS ; Point to character set + +@GPC_DECODE_CHAR_BYTE: + + MOV SI, [BP].GPC_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].GPC_T_SETO, SI ; And save new Pointer... + + mov ax,0 ; Clear AX + + ;mov bl,0 ; Clear BL + mov bl,0 + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_LEFT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_LEFT1BITS: + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_LEFT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@GPC_NO_LEFT0BITS: + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_MIDDLE1BITS ; Skip if no pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE1BITS: + XOR AL, ALL_PLANES ; Invert mask for Background + JZ @GPC_NO_MIDDLE0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE0BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @GPC_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_RIGHT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT1BITS: + + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_RIGHT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT0BITS: + DEC DI ; Adjust for Next Line Advance + +@GPC_NEXT_LINE: + ADD DI, [BP].GPC_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].GPC_Lines ; Count Down Lines + JZ @GPC_EXIT ; Ok... Done! + + JMP @GPC_DECODE_CHAR_BYTE ; Again! Hey! + +@GPC_EXIT: + ADD SP, 08 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 10 ; Exit and Clean up Stack + +GPRINTC ENDP + + +;========================================== +;TGPRINTC (CharNum%, Xpos%, Ypos%, ColorF%) +;========================================== +; +; Transparently draws an ASCII Text Character using the +; currently selected 8x8 font on the active display page. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; +; EXIT: No meaningful values returned +; + +TGP_STACK STRUC + TGP_Width DW ? ; Screen Width-1 + TGP_Lines DB ?,? ; Scan lines to Decode + TGP_T_SETS DW ? ; Saved Charset Segment + TGP_T_SETO DW ? ; Saved Charset Offset + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TGP_ColorF DB ?,? ; Text Color + TGP_Ypos DW ? ; Y Position to Print at + TGP_Xpos DW ? ; X position to Print at + TGP_Char DB ?,? ; Character to Print +TGP_STACK ENDS + + PUBLIC TGPRINTC + +TGPRINTC PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].TGP_Width, BX ; Save for later use + + MUL [BP].TGP_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].TGP_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 1 ; Bytes into Line = Xpos/4 + SHR AX, 1 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].TGP_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @TGP_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @TGP_Set_Char ; Go Setup Character Ptr + +@TGP_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@TGP_Set_Char: + MOV [BP].TGP_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].TGP_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].TGP_Lines, AL ; Save on Stack + + MOV DS, [BP].TGP_T_SETS ; Point to character set + +@TGP_DECODE_CHAR_BYTE: + + MOV SI, [BP].TGP_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].TGP_T_SETO, SI ; And save new Pointer... + + MOV AH, [BP].TGP_ColorF ; Get Foreground Color + + mov bl,0 ; Clear BL + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_LEFT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@TGP_NO_LEFT1BITS: + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_MIDDLE1BITS ; Skip if no pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_MIDDLE1BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @TGP_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_RIGHT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_RIGHT1BITS: + + DEC DI ; Adjust for Next Line Advance + +@TGP_NEXT_LINE: + ADD DI, [BP].TGP_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].TGP_Lines ; Count Down Lines + JZ @TGP_EXIT ; Ok... Done! + + JMP @TGP_DECODE_CHAR_BYTE ; Again! Hey! + +@TGP_EXIT: + ADD SP, 08 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 8 ; Exit and Clean up Stack + +TGPRINTC ENDP + + +;=============================================================== +;PRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;=============================================================== +; +; Routine to quickly Print a null terminated ASCII string on the +; active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +PS_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + PS_ColorB DW ? ; Background Color + PS_ColorF DW ? ; Text Color + PS_Ypos DW ? ; Y Position to Print at + PS_Xpos DW ? ; X position to Print at + PS_Len DW ? ; Maximum Length of string to print + PS_Text DW ?,? ; Far Ptr to Text String +PS_STACK ENDS + + PUBLIC PRINT_STR + +PRINT_STR PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + +@PS_Print_It: + + MOV CX, [BP].PS_Len ; Get Remaining text Length + JCXZ @PS_Exit ; Exit when out of text + + LES DI, d [BP].PS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @PS_Exit ; Exit if null character + + DEC [BP].PS_Len ; Remaining Text length-- + INC [BP].PS_Text ; Point to Next text char + + ; Set up Call to GPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].PS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].PS_Xpos, BX ; Save for next time through + + MOV BX, [BP].PS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].PS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + MOV BX, [BP].PS_ColorB ; Get Background Color + PUSH BX ; Set ColorB Parameter + + CALL f GPRINTC ; Print Character! + JMP s @PS_Print_It ; Process next character + +@PS_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 14 ; Exit and Clean up Stack + +PRINT_STR ENDP + + +;================================================================ +;TPRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================================ +; +; Routine to quickly transparently Print a null terminated ASCII +; string on the active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; +; EXIT: No meaningful values returned +; + +TPS_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TPS_ColorF DW ? ; Text Color + TPS_Ypos DW ? ; Y Position to Print at + TPS_Xpos DW ? ; X position to Print at + TPS_Len DW ? ; Maximum Length of string to print + TPS_Text DW ?,? ; Far Ptr to Text String +TPS_STACK ENDS + + PUBLIC TPRINT_STR + +TPRINT_STR PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + +@TPS_Print_It: + + MOV CX, [BP].TPS_Len ; Get Remaining text Length + JCXZ @TPS_Exit ; Exit when out of text + + LES DI, d [BP].TPS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @TPS_Exit ; Exit if null character + + DEC [BP].TPS_Len ; Remaining Text length-- + INC [BP].TPS_Text ; Point to Next text char + + ; Set up Call to TGPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].TPS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].TPS_Xpos, BX ; Save for next time through + + MOV BX, [BP].TPS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].TPS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + CALL f TGPRINTC ; Print Character! + JMP s @TPS_Print_It ; Process next character + +@TPS_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +TPRINT_STR ENDP + + +;=========================================== +;SET_DISPLAY_FONT(SEG FontData, FontNumber%) +;=========================================== +; +; Allows the user to specify their own font data for +; wither the lower or upper 128 characters. +; +; ENTRY: FontData = Far Pointer to Font Bitmaps +; FontNumber = Which half of set this is +; = 0, Lower 128 characters +; = 1, Upper 128 characters +; +; EXIT: No meaningful values returned +; + +SDF_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDF_Which DW ? ; Hi Table/Low Table Flag + SDF_Font DD ? ; Far Ptr to Font Table +SDF_STACK ENDS + + PUBLIC SET_DISPLAY_FONT + +SET_DISPLAY_FONT PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, [BP].SDF_Font ; Get Far Ptr to Font + + MOV SI, o CHARSET_LOW ; Assume Lower 128 chars + TEST [BP].SDF_Which, 1 ; Font #1 selected? + JZ @SDF_Set_Font ; If not, skip ahead + + MOV SI, o CHARSET_HI ; Ah, really it's 128-255 + +@SDF_Set_Font: + MOV [SI], DI ; Set Font Pointer Offset + MOV [SI+2], ES ; Set Font Pointer Segment + + POP BP ; Restore Registers + RET 6 ; We are Done.. Outa here + +SET_DISPLAY_FONT ENDP + + + ; ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +;====================================================== +;DRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;====================================================== +; +; Draws a variable sized Graphics Bitmap such as a +; picture or an Icon on the current Display Page in +; Mode X. The Bitmap is stored in a linear byte array +; corresponding to (0,0) (1,0), (2,0) .. (Width, Height) +; This is the same linear manner as mode 13h graphics. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +DB_STACK STRUC + DB_LineO DW ? ; Offset to Next Line + DB_PixCount DW ? ; (Minimum) # of Pixels/Line + DB_Start DW ? ; Addr of Upper Left Pixel + DB_PixSkew DW ? ; # of bytes to Adjust EOL + DB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + DB_Height DW ? ; Height of Bitmap in Pixels + DB_Width DW ? ; Width of Bitmap in Pixels + DB_Ypos DW ? ; Y position to Draw Bitmap at + DB_Xpos DW ? ; X position to Draw Bitmap at + DB_Image DD ? ; Far Pointer to Graphics Bitmap +DB_STACK ENDS + + PUBLIC DRAW_BITMAP + +DRAW_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].DB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].DB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 1 ; Xpos/4 = Offset Into Line + SHR BX, 1 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].DB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].DB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 1 ; /4 = width in bands + SHR BX, 1 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].DB_LineO, AX ; Save Line Width offset + MOV [BP].DB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].DB_PixSkew, DX ; Also End of Line Skew + MOV [BP].DB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@DB_COPY_PLANE: + + LDS SI, [BP].DB_Image ; DS:SI-> Source Image + MOV DX, [BP].DB_Height ; # of Lines to Copy + MOV DI, [BP].DB_Start ; ES:DI-> Dest pos + +@DB_COPY_LINE: + MOV CX, [BP].DB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @DB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@DB_COPY_LOOP: + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @DB_COPY_LOOP ; if so, do another block + +@DB_COPY_REMAINDER: + JCXZ @DB_NEXT_LINE ; Any Pixels left on line + +@DB_COPY2: + MOVSB ; Copy Bitmap Pixel + ADD SI,3 ; Skip to Next Byte in same plane + LOOPx CX, @DB_COPY2 ; Pixels to Copy--, Loop until done + +@DB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].DB_SkewFlag ; Get Skew Count + JZ @DB_NEXT2 ; if no partial pixels + + MOVSB ; Copy Bitmap Pixel + DEC DI ; Back up to align + DEC SI ; Back up to align + +@DB_NEXT2: + ADD SI, [BP].DB_PixSkew ; Adjust Skew + ADD DI, [BP].DB_LineO ; Set to Next Display Line + LOOPx DX, @DB_COPY_LINE ; Lines to Copy--, Loop if more + + ; Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @DB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].DB_Start, 0 ; Screen Addr =+Carry + INC w [BP].DB_Image ; Start @ Next Byte + + SUB [BP].DB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].DB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP s @DB_COPY_PLANE ; Go Copy the Next Plane + +@DB_Exit: + ADD SP, 10 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +DRAW_BITMAP ENDP + + +;======================================================= +;TDRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;======================================================= +; +; Transparently Draws a variable sized Graphics Bitmap +; such as a picture or an Icon on the current Display Page +; in Mode X. Pixels with a value of 0 are not drawn, +; leaving the previous "background" contents intact. +; +; The Bitmap format is the same as for the DRAW_BITMAP function. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +TB_STACK STRUC + TB_LineO DW ? ; Offset to Next Line + TB_PixCount DW ? ; (Minimum) # of Pixels/Line + TB_Start DW ? ; Addr of Upper Left Pixel + TB_PixSkew DW ? ; # of bytes to Adjust EOL + TB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TB_Height DW ? ; Height of Bitmap in Pixels + TB_Width DW ? ; Width of Bitmap in Pixels + TB_Ypos DW ? ; Y position to Draw Bitmap at + TB_Xpos DW ? ; X position to Draw Bitmap at + TB_Image DD ? ; Far Pointer to Graphics Bitmap +TB_STACK ENDS + + PUBLIC TDRAW_BITMAP + +TDRAW_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].TB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].TB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 1 ; Xpos/4 = Offset Into Line + SHR BX, 1 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].TB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].TB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 1 ; /4 = width in bands + SHR BX, 1 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].TB_LineO, AX ; Save Line Width offset + MOV [BP].TB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].TB_PixSkew, DX ; Also End of Line Skew + MOV [BP].TB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@TB_COPY_PLANE: + + LDS SI, [BP].TB_Image ; DS:SI-> Source Image + MOV DX, [BP].TB_Height ; # of Lines to Copy + MOV DI, [BP].TB_Start ; ES:DI-> Dest pos + + ; Here AH is set with the value to be considered + ; "Transparent". It can be changed! + + MOV AH, 0 ; Value to Detect 0 + +@TB_COPY_LINE: + MOV CX, [BP].TB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @TB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@TB_COPY_LOOP: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_01 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_01: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_02 ; Skip ahead if so + MOV ES:[DI+1], AL ; Copy Pixel to VGA screen + +@TB_SKIP_02: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_03 ; Skip ahead if so + MOV ES:[DI+2], AL ; Copy Pixel to VGA screen + +@TB_SKIP_03: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_04 ; Skip ahead if so + MOV ES:[DI+3], AL ; Copy Pixel to VGA screen + +@TB_SKIP_04: + ADD DI, 4 ; Adjust Pixel Write Location + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @TB_COPY_LOOP ; if so, do another block + +@TB_COPY_REMAINDER: + JCXZ @TB_NEXT_LINE ; Any Pixels left on line + +@TB_COPY2: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_05 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_05: + INC DI ; Advance Dest Addr + LOOPx CX, @TB_COPY2 ; Pixels to Copy--, Loop until done + +@TB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].TB_SkewFlag ; Get Skew Count + JZ @TB_NEXT2 ; if no partial pixels + + LODSB ; Get Pixel Value in AL + DEC SI ; Backup to Align + CMP AL, AH ; It is "Transparent"? + JE @TB_NEXT2 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_NEXT2: + ADD SI, [BP].TB_PixSkew ; Adjust Skew + ADD DI, [BP].TB_LineO ; Set to Next Display Line + LOOPx DX, @TB_COPY_LINE ; Lines to Copy--, Loop if More + + ;Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @TB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].TB_Start, 0 ; Screen Addr =+Carry + INC w [BP].TB_Image ; Start @ Next Byte + + SUB [BP].TB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].TB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP @TB_COPY_PLANE ; Go Copy the next Plane + +@TB_Exit: + ADD SP, 10 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +TDRAW_BITMAP ENDP + + + ; ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +;================================== +;COPY_PAGE (SourcePage%, DestPage%) +;================================== +; +; Duplicate on display page onto another +; +; ENTRY: SourcePage = Display Page # to Duplicate +; DestPage = Display Page # to hold copy +; +; EXIT: No meaningful values returned +; + +CP_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + CP_DestP DW ? ; Page to hold copied image + CP_SourceP DW ? ; Page to Make copy from +CP_STACK ENDS + + PUBLIC COPY_PAGE + +COPY_PAGE PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + CLD ; Block Xfer Forwards + + ; Make sure Page #'s are valid + + MOV AX, [BP].CP_SourceP ; Get Source Page # + CMP AX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + MOV BX, [BP].CP_DestP ; Get Destination Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + CMP AX, BX ; Pages #'s the same? + JE @CP_Exit ; if so, abort + + ; Setup DS:SI and ES:DI to Video Pages + + SHL BX, 1 ; Scale index to Word + MOV DI, PAGE_ADDR[BX] ; Offset to Dest Page + + MOV BX, AX ; Index to Source page + SHL BX, 1 ; Scale index to Word + MOV SI, PAGE_ADDR[BX] ; Offset to Source Page + + MOV CX, PAGE_SIZE ; Get size of Page + MOV AX, CURRENT_SEGMENT ; Get Video Mem Segment + MOV ES, AX ; ES:DI -> Dest Page + MOV DS, AX ; DS:SI -> Source Page + + ; Setup VGA registers for Mem to Mem copy + + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + OUT_16 SC_Index, ALL_PLANES_ON ; Copy all Planes + + ; Note.. Do *NOT* use MOVSW or MOVSD - they will + ; Screw with the latches which are 8 bits x 4 + + REP MOVSB ; Copy entire Page! + + ; Reset VGA for normal memory access + + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = off + +@CP_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 4 ; Exit and Clean up Stack + +COPY_PAGE ENDP + + +;========================================================================== +;COPY_BITMAP (SourcePage%, X1%, Y1%, X2%, Y2%, DestPage%, DestX1%, DestY1%) +;========================================================================== +; +; Copies a Bitmap Image from one Display Page to Another +; This Routine is Limited to copying Images with the same +; Plane Alignment. To Work: (X1 MOD 4) must = (DestX1 MOD 4) +; Copying an Image to the Same Page is supported, but results +; may be defined when the when the rectangular areas +; (X1, Y1) - (X2, Y2) and (DestX1, DestY1) - +; (DestX1+(X2-X1), DestY1+(Y2-Y1)) overlap... +; No Paramter checking to done to insure that +; X2 >= X1 and Y2 >= Y1. Be Careful... +; +; ENTRY: SourcePage = Display Page # with Source Image +; X1 = Upper Left Xpos of Source Image +; Y1 = Upper Left Ypos of Source Image +; X2 = Lower Right Xpos of Source Image +; Y2 = Lower Right Ypos of Source Image +; DestPage = Display Page # to copy Image to +; DestX1 = Xpos to Copy UL Corner of Image to +; DestY1 = Ypos to Copy UL Corner of Image to +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +CB_STACK STRUC + CB_Height DW ? ; Height of Image in Lines + CB_Width DW ? ; Width of Image in "bands" + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + CB_DestY1 DW ? ; Destination Ypos + CB_DestX1 DW ? ; Destination Xpos + CB_DestP DW ? ; Page to Copy Bitmap To + CB_Y2 DW ? ; LR Ypos of Image + CB_X2 DW ? ; LR Xpos of Image + CB_Y1 DW ? ; UL Ypos of Image + CB_X1 DW ? ; UL Xpos of Image + CB_SourceP DW ? ; Page containing Source Bitmap +CB_STACK ENDS + + PUBLIC COPY_BITMAP + +COPY_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 4 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + ; Prep Registers (and keep jumps short!) + + MOV ES, CURRENT_SEGMENT ; ES -> VGA Ram + CLD ; Block Xfer Forwards + + ; Make sure Parameters are valid + + MOV BX, [BP].CB_SourceP ; Get Source Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV CX, [BP].CB_DestP ; Get Destination Page # + CMP CX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV AX, [BP].CB_X1 ; Get Source X1 + XOR AX, [BP].CB_DestX1 ; Compare Bits 0-1 + AND AX, PLANE_BITS ; Check Plane Bits + JNZ @CB_Abort ; They should cancel out + + ; Setup for Copy processing + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + + ; Compute Info About Images, Setup ES:SI & ES:DI + + MOV AX, [BP].CB_Y2 ; Height of Bitmap in lines + SUB AX, [BP].CB_Y1 ; is Y2 - Y1 + 1 + INC AX ; (add 1 since were not 0 based) + MOV [BP].CB_Height, AX ; Save on Stack for later use + + MOV AX, [BP].CB_X2 ; Get # of "Bands" of 4 Pixels + MOV DX, [BP].CB_X1 ; the Bitmap Occupies as X2-X1 + SHR AX, 1 ; Get X2 Band (X2 / 4) + SHR DX, 1 ; Get X1 Band (X1 / 4) + SHR AX, 1 ; Get X2 Band (X2 / 4) + SHR DX, 1 ; Get X1 Band (X1 / 4) + SUB AX, DX ; AX = # of Bands - 1 + INC AX ; AX = # of Bands + MOV [BP].CB_Width, AX ; Save on Stack for later use + + SHL BX, 1 ; Scale Source Page to Word + MOV SI, PAGE_ADDR[BX] ; SI = Offset of Source Page + MOV AX, [BP].CB_Y1 ; Get Source Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD SI, AX ; SI = Offset to Line Y1 + MOV AX, [BP].CB_X1 ; Get Source X1 + SHR AX, 1 ; X1 / 4 = Byte offset + SHR AX, 1 ; X1 / 4 = Byte offset + ADD SI, AX ; SI = Byte Offset to (X1,Y1) + + MOV BX, CX ; Dest Page Index to BX + SHL BX, 1 ; Scale Source Page to Word + MOV DI, PAGE_ADDR[BX] ; DI = Offset of Dest Page + MOV AX, [BP].CB_DestY1 ; Get Dest Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD DI, AX ; DI = Offset to Line Y1 + MOV AX, [BP].CB_DestX1 ; Get Dest X1 + SHR AX, 1 ; X1 / 4 = Byte offset + SHR AX, 1 ; X1 / 4 = Byte offset + ADD DI, AX ; DI = Byte Offset to (D-X1,D-Y1) + + MOV CX, [BP].CB_Width ; CX = Width of Image (Bands) + DEC CX ; CX = 1? + JE @CB_Only_One_Band ; 0 Means Image Width of 1 Band + + MOV BX, [BP].CB_X1 ; Get Source X1 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 00?) + JZ @CB_Check_Right ; if so, check right alignment + JNZ @CB_Left_Band ; not aligned? well.. + +@CB_Abort: + mov ax,0 ; Return False (Failure) + JMP @CB_Exit ; and Finish Up + + ; Copy when Left & Right Clip Masks overlap... + +@CB_Only_One_Band: + MOV BX, [BP].CB_X1 ; Get Left Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[BX] ; Get Left Edge Mask + MOV BX, [BP].CB_X2 ; Get Right Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[BX] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + mov bx,0 ; BX = Offset into Image + +@CB_One_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_One_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_One_Loop ; Loop until Finished + +@CB_One_Done: + JMP @CB_Finish ; Outa Here! + + ; Copy Left Edge of Bitmap + +@CB_Left_Band: + + OUT_8 SC_Data, Left_Clip_Mask[BX] ; Set Left Edge Plane Mask + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + mov bx,0 ; BX = Offset into Image + +@CB_Left_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Left_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Left_Loop ; Loop until Finished + +@CB_Left_Done: + INC DI ; Move Dest Over 1 band + INC SI ; Move Source Over 1 band + DEC [BP].CB_Width ; Band Width-- + + ; Determine if Right Edge of Bitmap needs special copy + +@CB_Check_Right: + MOV BX, [BP].CB_X2 ; Get Source X2 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 11?) + CMP BL, 03h ; Plane = 3? + JE @CB_Copy_Middle ; Copy the Middle then! + + ; Copy Right Edge of Bitmap + +@CB_Right_Band: + + OUT_8 SC_Data, Right_Clip_Mask[BX] ; Set Right Edge Plane Mask + + DEC [BP].CB_Width ; Band Width-- + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + MOV BX, [BP].CB_Width ; BX = Offset to Right Edge + +@CB_Right_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Right_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Right_Loop ; Loop until Finished + +@CB_Right_Done: + + ; Copy the Main Block of the Bitmap + +@CB_Copy_Middle: + + MOV CX, [BP].CB_Width ; Get Width Remaining + JCXZ @CB_Finish ; Exit if Done + + OUT_8 SC_Data, ALL_PLANES ; Copy all Planes + + MOV DX, SCREEN_WIDTH ; Get Width of Screen minus + SUB DX, CX ; Image width (for Adjustment) + MOV AX, [BP].CB_Height ; AX = # of Lines to Copy + MOV BX, CX ; BX = Quick REP reload count + MOV CX, ES ; Move VGA Segment + MOV DS, CX ; Into DS + + ; Actual Copy Loop. REP MOVSB does the work + +@CB_Middle_Copy: + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + LOOPjz AX, @CB_Finish ; Exit Loop if Finished + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + LOOPx AX, @CB_Middle_Copy ; Copy Lines until Done + +@CB_Finish: + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = on + +@CB_Exit: + ADD SP, 04 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 16 ; Exit and Clean up Stack + +COPY_BITMAP ENDP + + END ; End of Code Segment diff --git a/src/lib/modex/demos/c/modex.bi b/src/lib/modex/demos/c/modex.bi new file mode 100755 index 00000000..6b1d7afe --- /dev/null +++ b/src/lib/modex/demos/c/modex.bi @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/src/lib/modex/demos/c/modex.h b/src/lib/modex/demos/c/modex.h new file mode 100755 index 00000000..1381abb6 --- /dev/null +++ b/src/lib/modex/demos/c/modex.h @@ -0,0 +1,76 @@ + +#ifndef __MODEX_H +#define __MODEX_H + + /* ===== SCREEN RESOLUTIONS ===== */ + +#define Mode_320x200 0 +#define Mode_320x400 1 +#define Mode_360x200 2 +#define Mode_360x400 3 +#define Mode_320x240 4 +#define Mode_320x480 5 +#define Mode_360x240 6 +#define Mode_360x480 7 + + /* ===== MODE X SETUP ROUTINES ===== */ + +int far pascal set_vga_modex (int Mode, int MaxXpos, int MaxYpos, int Pages); +int far pascal set_modex (int Mode); + + /* ===== BASIC GRAPHICS PRIMITIVES ===== */ + +void far pascal clear_vga_screen (int Color); +void far pascal set_point (int Xpos, int Ypos, int Color); +int far pascal read_point (int Xpos, int Ypos); +void far pascal fill_block (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); +void far pascal draw_line (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); + + /* ===== DAC COLOR REGISTER ROUTINES ===== */ + +void far pascal set_dac_register (int RegNo, int Red, int Green, int Blue); +void far pascal get_dac_register (int RegNo, int* Red, int* Green, int* Blue); +void far pascal load_dac_registers (char far *PalData, int StartReg, + int EndReg, int VSync); +void far pascal readd_dac_registers (char far *PalData, int StartReg, + int EndReg); + + /* ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== */ + +void far pascal set_active_page (int PageNo); +int far pascal get_active_page (void); +void far pascal set_display_page (int PageNo); +int far pascal get_display_page (void); +void far pascal set_window (int DisplayPage, int XOffset, int YOffset); +int far pascal get_x_offset (void); +int far pascal get_y_offset (void); +void far pascal sync_display (void); + + /* ===== TEXT DISPLAY ROUTINES ===== */ + +void far pascal gprintc (int CharNum, int Xpos, int Ypos, int ColorF, + int ColorB); +void far pascal tgprintc (int CharNum, int Xpos, int Ypos, int ColorF); +void far pascal print_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF, int ColorB); +void far pascal tprint_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF); +void far pascal set_display_font (char far *FontData, int FontNumber); + + /* ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== */ + +void far pascal draw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); +void far pascal tdraw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); + + /* ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== */ + +void far pascal copy_page (int SourcePage, int DestPage); +void far pascal copy_bitmap (int SourcePage, int X1, int Y1, int X2, int Y2, + int DestPage, int DestX1, int DestY1); + + +#endif diff --git a/src/lib/modex/demos/c/utls-asm.bat b/src/lib/modex/demos/c/utls-asm.bat new file mode 100755 index 00000000..d996978f --- /dev/null +++ b/src/lib/modex/demos/c/utls-asm.bat @@ -0,0 +1 @@ +MASM c_utils, c_utils, c_utils, nul; \ No newline at end of file diff --git a/src/lib/modex/demos/c/w.sh b/src/lib/modex/demos/c/w.sh new file mode 100755 index 00000000..59f63610 --- /dev/null +++ b/src/lib/modex/demos/c/w.sh @@ -0,0 +1,3 @@ +#! /bin/bash +wmake clean;wmake +cp x-demo.exe ../../../../../ diff --git a/src/lib/modex/demos/c/x-demo.c b/src/lib/modex/demos/c/x-demo.c new file mode 100755 index 00000000..dfe9a3e0 --- /dev/null +++ b/src/lib/modex/demos/c/x-demo.c @@ -0,0 +1,786 @@ +/* X-DEMO.C - a Mode "X" Demo */ +/* By Matt Pritchard, 14 Apr, 1993 */ + +#include +#include + +#include "modex.h" +#include "c_utils.h" + +#define MAX_SHAPES 32 +#define MAX_SPRITES 64 + + /* routines in this file */ + +void demo_res (int, int, int); +int get_key (void); +void error_out (char*); +void load_shapes (void); +int int_sqrt (int, int); +void page_demo (void); + + /* Structures for Sprites */ + +struct Shape +{ + unsigned char Image[512]; + int X_Width; + int Y_Width; +} Img [MAX_SHAPES]; + +struct Sprite +{ + int X_pos; + int Y_pos; + int X_Dir; + int Y_Dir; + int Shape; + int Last_X [2]; + int Last_Y [2]; +} Obj [MAX_SPRITES]; + + + /* MAIN */ + + +int main(int argc, char *argv[]) +{ + + /* if (argc > 0) + { + while (argc > 0) + { + dos_print ("Unknown Argument: "); + dos_print (makefp argv[argc]); + argc--; + } + return (0); + + } + */ + + init_random (); + + load_shapes (); + + demo_res ( Mode_320x200, 320, 200 ); + demo_res ( Mode_320x400, 320, 400 ); + + demo_res ( Mode_360x200, 360, 200 ); + demo_res ( Mode_360x400, 360, 400 ); + + demo_res ( Mode_320x240, 320, 240 ); + demo_res ( Mode_320x480, 320, 480 ); + + demo_res ( Mode_360x240, 360, 240 ); + demo_res ( Mode_360x480, 360, 480 ); + + page_demo (); + + set_video_mode (3); + dos_print ("This Mode X Demo is Finished"); + return (0); + +} + + + /* Demonstrate a given resolution */ + + +void demo_res (int Screen_Mode, int X_max, int Y_max) +{ + +char *Error1 = "Failure while calling SET_MODEX"; +char *Error2 = "Failure during READ_PIXEL test"; + +char *Abort_Msg = "Demo aborted by User"; + +char *Demo_Msg = " This is a MODE X demo "; +char *Scrn_Msg = "Screen Resolution is by "; +char *Cont_Msg = "Press to Continue"; + +char *Line_Msg = "LINE TEST"; +char *Fill_Msg = "FILL TEST"; +char *Pixel_Msg = "PIXEL TEST"; + +char Text[10]; + +int x1, y1, x2, y2 = 0; +int x, y, z = 0; +int X_Center, gap = 0; + + + if (set_modex (Screen_Mode) == 0) + { + error_out (Error1); + } + + X_Center = X_max / 2; + + x1 = 10; + y1 = 10; + x2 = X_max - 1; + y2 = Y_max - 1; + + for (z = 0; z <= 3; z++) + { + y = 31 - z -z; + draw_line (x1+z, y1+z, x2-z, y1+z, y); + draw_line (x1+z, y1+z, x1+z, y2-z, y); + draw_line (x1+z, y2-z, x2-z, y2-z, y); + draw_line (x2-z, y1+z, x2-z, y2-z, y); + } + + for (x = 0; x < (X_max / 10); x++) + { + tgprintc (48 + ((x+1) % 10), x*10+1, 1, 9 + ((x/8) % 7) ); + draw_line (x*10+9, 0, x*10+9, 3, c_bWHITE); + } + + for (y = 0; y < (Y_max / 10); y++) + { + tgprintc (48 + ((y+1) % 10), 1, y*10+1, 9 + ((y/10) % 7) ); + draw_line (0, y*10+9, 3, y*10+9, c_bWHITE); + } + + for (x = 0; x <= 63; x++) + { + z = 15 + (x * 3 / 4); + set_dac_register (64+x, z, z, z); + set_dac_register (128+x, 0, z, z); + + draw_line (103-x, 60, 40+x, 123, 64+x); + draw_line (40, 60+x, 103, 123-x, 128+x); + + } + + tprint_str (Line_Msg, 9, 37, 130, c_BLUE); + + y = 60; + gap = 0; + for (x = 0; x <= 9; x++) + { + fill_block (120, y, 120+x, y+gap, 64+x); + fill_block (140 - (15-x), y, 150+x, y+gap, 230+x); + fill_block (170 - (15-x), y, 170, y+gap, 128+x); + y = y + gap + 2; + gap++; + } + + tprint_str (Fill_Msg, 9, 110, 46, c_GREEN); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + set_point (x, y, z); + } + } + + tprint_str (Pixel_Msg, 10, 182, 130, c_RED); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + if (read_point(x, y) != z) + { + error_out (Error2); + } + } + } + + print_str (Demo_Msg, 23, X_Center - 92, 20, c_bRED, c_BLUE); + + x = X_Center - 124; + print_str (Scrn_Msg, 28, x, 30, c_bGREEN, c_BLACK); + + sprintf (Text, "%3d", X_max); + print_str (Text, 3, x+168, 30, c_bPURPLE, c_BLACK); + + sprintf (Text, "%3d", Y_max); + print_str (Text, 3, x + 224, 30, c_bWHITE, c_BLACK); + + for (x = 0; x <= 15; x++) + { + set_dac_register (230+x, 63-x*4, 0, 15+x*3); + draw_line (30+x, Y_max-6-x, X_max-20-x, Y_max-6-x, 230+x); + } + + tprint_str (Cont_Msg, 27, X_Center - 103, Y_max-18, c_YELLOW); + + if (get_key () == Ky_ESC) + { + error_out (Abort_Msg); + } + + return ; + +} + + + /* Wait for a Keystroke */ + + +int get_key(void) +{ + +int c = 0; + + while (c == 0) + { + c = scan_keyboard (); + } + + return (c); + +} + + + /* Error Handling Routine */ + + +void error_out (char * text) +{ + + set_video_mode (3); + dos_print (text); + exit (EXIT_SUCCESS); + +} + + + /* Routine to generate random sprites */ + + +void load_shapes () +{ + +unsigned char Grid[33][33]; + +char *Error1 = "Bad Shape Selected Error"; + +int Shape; +int x, y, z; +int Style, Color; +int X_Width, Y_Width, Center, S_Width; +int Hollow_X, Hollow_Y; + + for (Shape = 0; Shape < MAX_SHAPES; Shape++) + { + for (y = 0; y <= 32; y++) + { + for (x = 0; x <= 32; x++) + { + Grid[x][y] = c_BLACK; + } + } + + Style = random_int (6); + Color = 1 + random_int (15); + + switch (Style) + + { + /* SOLID BOXES */ + + case 0: + + { + do + { + X_Width = 3 + random_int(30); + Y_Width = 3 + random_int(30); + + } while ( (X_Width * Y_Width) >= 512); + + for (x = 1; x <= X_Width; x++) + { + for (y = 1; y <= Y_Width; y++) + { + Grid[x][y] = Color; + } + } + + break; + + } + /* HOLLOW BOXES */ + + case 1: + + { + do { + X_Width = 6 + random_int(27); + Y_Width = 6 + random_int(27); + } while ( (X_Width * Y_Width) >= 512); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Grid[x][y] = Color; + } + } + + Hollow_X = 1 + random_int ((X_Width / 2) -1); + Hollow_Y = 1 + random_int ((Y_Width / 2) -1); + + for (y = Hollow_Y+1; y <= Y_Width-Hollow_Y; y++) + { + for (x = Hollow_X+1; x <= X_Width-Hollow_X; x++) + { + Grid[x][y] = c_BLACK; + } + } + + break; + + } + + /* SOLID DIAMOND */ + + case 2: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + + break; + + } + + /* HOLLOW DIAMOND */ + + case 3: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + S_Width = random_int (Center); + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + if ( x+(Center-y) >= S_Width ) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + } + + break; + + } + + /* BALL */ + + case 4: + + { + + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if (z < Center) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + break; + } + + /* HOLLOW BALLS */ + + case 5: + + { + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + S_Width = random_int (X_Width); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if ( (z < Center) && (z >= S_Width) ) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + + break; + } + + default: + + { + error_out (Error1); + break; + + } + + } + + z = 0; + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Img[Shape].Image[z] = Grid[x][y]; + z++; + } + } + + Img[Shape].X_Width = X_Width; + Img[Shape].Y_Width = Y_Width; + + } + + return; +} + + + /* Quickie Psuedo Integer Square Root Routine */ + + +int int_sqrt ( int x, int y ) +{ + +int Sqr_Table[12] = {1, 4, 9, 6, 25, 36, 49, 64, 81, 100, 121, 144}; + +int r, d; + + d = (x * x) + (y * y); + r = 0; + + while ( d >= Sqr_Table[r] ) + { + r++; + } + + return (r); + +} + + + /* The Bit Sprite Demo */ + + +void page_demo () +{ + +char *Error1 = "Failure during SET_VGA_MODEX (0, 320, 200, 2) call"; + +int Last_Objects[2], Visible_Objects; + +int Screen_X = 384; +int Screen_Y = 224; + +int x, y, z; +int c, dc; +int x1, y1, x2, y2; + +int Sprite_X, Sprite_Y; +int Current_Page; +int New_X, New_Y; + +int View_X, View_Y, View_Max, View_Cnt, View_XD, View_YD; +int Set_Color, Prev_Color, S_Dir, P_Dir; + +int Demo_Running = True; +int redo, code; + +int pee; +pee = set_vga_modex(Mode_320x200, Screen_X, Screen_Y, 3); + if ( pee > 0) + { + set_video_mode (3); + dos_print (Error1); + fprintf(stdout, "return value is %d\n", pee); + //error_out (Error1); + exit (EXIT_SUCCESS); + } + + set_active_page (0); + clear_vga_screen (c_BLACK); + + print_str ("This is a Test of the Following Functions:", 99, 10, 9, c_bWHITE, c_BLACK); + + draw_line (10, 18, 350, 18, c_YELLOW); + print_str ("SET_ACTIVE_PAGE", 99, 10, 20, c_bBLUE, c_BLACK); + print_str ("SET_DISPLAY_PAGE", 99, 10, 30, c_GREEN, c_BLACK); + print_str ("SET_DAC_REGISTER", 99, 10, 40, c_RED, c_BLACK); + print_str ("CLEAR_VGA_SCREEN", 99, 10, 50, c_CYAN, c_BLACK); + + print_str ("TDRAW_BITMAP", 99, 10, 60, c_PURPLE, c_BLACK); + print_str ("COPY_PAGE", 99, 10, 70, c_GREEN, c_BLACK); + print_str ("COPY_BITMAP", 99, 10, 80, c_CYAN, c_BLACK); + + print_str ("GPRINTC", 99, 10, 90, c_BLUE, c_BLACK); + print_str ("TGPRINTC", 99, 10, 100, c_GREEN, c_BLACK); + print_str ("SET_WINDOW", 99, 10, 110, c_RED, c_BLACK); + + print_str ("VIRTUAL SCREEN SIZES", 20, 190, 20, c_bBLUE, c_BLACK); + print_str (" SMOOTH SCROLLING", 20, 190, 30, c_GREEN, c_BLACK); + print_str (" SPRITE ANIMATION", 20, 190, 40, c_CYAN, c_BLACK); + print_str (" PAGE FLIPPING", 20, 190, 50, c_RED, c_BLACK); + print_str (" COLOR CYCLING", 20, 190, 60, c_PURPLE, c_BLACK); + + for (x = 0; x <=60; x++) + { + set_dac_register (50 + x, 3 + x, 0, 60 - x); + set_dac_register (150 + x, 3 + x, 0, 60 - x); + } + + c = 0; + dc = 1; + for (x = 0; x <= (Screen_X / 2); x++) + { + draw_line (Screen_X / 2 - 1, Screen_Y / 4, x, Screen_Y - 1, c + 50); + draw_line (Screen_X / 2, Screen_Y / 4, Screen_X - x - 1, Screen_Y - 1, c + 50); + c+= dc; + if ((c == 0) || (c == 60) ) { dc = -dc;} + } + + tprint_str ("Press to Continue", 99, 72, 190, c_bWHITE); + tprint_str ("< > = Faster < > = Slower", 99, 72, 204, c_bGREEN); + tprint_str ("< > = Fewer Shapes < > = More Shapes", 99, 32, 218, c_bCYAN); + + tgprintc (43, 80, 204, c_YELLOW); + tgprintc (45, 200, 204, c_YELLOW); + + tgprintc (25, 40, 218, c_YELLOW); + tgprintc (24, 200, 218, c_YELLOW); + + copy_page (0, 1); + copy_page (0, 2); + + for (x = 0; x < MAX_SPRITES; x++) + { + do { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + + Obj[x].Shape = x % MAX_SHAPES; + + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + Obj[x].X_pos = 1 + random_int(Screen_X - Sprite_X - 2); + Obj[x].Y_pos = 1 + random_int(Screen_Y - Sprite_Y - 2); + + Obj[x].Last_X[0] = Obj[x].X_pos; + Obj[x].Last_X[1] = Obj[x].X_pos; + Obj[x].Last_Y[0] = Obj[x].Y_pos; + Obj[x].Last_Y[1] = Obj[x].Y_pos; + + } + + Current_Page = 0; + + View_X = 0; + View_Y = 0; + View_Max = 3; + View_Cnt = 0; + View_XD = 1; + View_YD = 1; + + Set_Color = 3; + S_Dir = 1; + Prev_Color = 0; + P_Dir = 1; + + Visible_Objects = MAX_SPRITES / 2; + Last_Objects[0] = 0; + Last_Objects[1] = 0; + + while (Demo_Running) + { + + set_active_page (Current_Page); + + /* Erase Old Images */ + + for (x = 0; x <= Last_Objects[Current_Page]; x++) + { + z = 2; + y = Obj[x].Shape; + x1 = Obj[x].Last_X[Current_Page]; + y1 = Obj[x].Last_Y[Current_Page]; + x2 = x1 + Img[y].X_Width -1; + y2 = y1 + Img[y].Y_Width -1; + + x1 = x1 & 0xfffc; + x2 = x2 | 0x0003; + + copy_bitmap (z, x1, y1, x2, y2, Current_Page, x1, y1); + } + + /* Draw new images */ + + for (x = 0; x <= Visible_Objects; x++) + { + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + /* Move Sprite */ + + do + { + redo = False; + New_X = Obj[x].X_pos + Obj[x].X_Dir; + + if (( New_X < 0 ) || (New_X + Sprite_X > Screen_X) ) + { + Obj[x].X_Dir = -Obj[x].X_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + Obj[x].X_pos = Obj[x].X_pos + Obj[x].X_Dir; + + + do + { + redo = False; + New_Y = Obj[x].Y_pos + Obj[x].Y_Dir; + + if ( (New_Y < 0) || (New_Y + Sprite_Y > Screen_Y) ) + { + Obj[x].Y_Dir = -Obj[x].Y_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + + Obj[x].Y_pos = Obj[x].Y_pos + Obj[x].Y_Dir; + + /* Draw Sprite */ + + tdraw_bitmap ((char far*) &Img[Obj[x].Shape], Obj[x].X_pos, Obj[x].Y_pos, Sprite_X, Sprite_Y); + + Obj[x].Last_X[Current_Page] = Obj[x].X_pos; + Obj[x].Last_Y[Current_Page] = Obj[x].Y_pos; + + } + + Last_Objects[Current_Page] = Visible_Objects; + + + /* Pan Screen Back & Forth */ + + View_Cnt++; + if (View_Cnt >= View_Max) + { + View_X+= View_XD; + if ( (View_X == 0) || (View_X == 39) ) {View_XD = -View_XD;} + if (View_XD < 0) + { + View_Y+= View_YD; + if ( (View_Y == 0) || (View_Y == 39) ) {View_YD = -View_YD;} + } + + set_window (Current_Page, View_X, View_Y); + + View_Cnt = 0; + } + else + { + set_display_page (Current_Page); + } + + /* Cycle Colors */ + + set_dac_register (50 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (50 + Set_Color, Set_Color, 10, 63 - Set_Color); + + set_dac_register (150 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (150 + Set_Color, 63, 63, Set_Color); + + Set_Color+= S_Dir; + if ( (Set_Color == 60) || (Set_Color == 0) ) {S_Dir = -S_Dir;} + + Prev_Color+= P_Dir; + if ( (Prev_Color == 60) || (Prev_Color == 0) ) {P_Dir = -P_Dir;} + + /* Check for Keystroke */ + + Current_Page = Current_Page ^ 0x01; + + code = scan_keyboard (); + + if (code == Ky_ESC) {Demo_Running = False;} + + if (code == Ky_Plus) + { + if (View_Max < 12) {View_Max++;} + } + + if (code == Ky_Minus) + { + if (View_Max > 1) {View_Max--;} + if (View_Cnt >= View_Max) {View_Cnt = 0;} + } + + if (code == Ky_Up) + { + if (Visible_Objects < MAX_SPRITES-1) {Visible_Objects++;} + } + + if (code == Ky_Down) + { + if (Visible_Objects > 0) {Visible_Objects--;} + } + + } + +} diff --git a/src/lib/modex/demos/c/x-demo.dsk b/src/lib/modex/demos/c/x-demo.dsk new file mode 100755 index 00000000..5573e71a Binary files /dev/null and b/src/lib/modex/demos/c/x-demo.dsk differ diff --git a/src/lib/modex/demos/c/x-demo.exe b/src/lib/modex/demos/c/x-demo.exe new file mode 100755 index 00000000..b4fee914 Binary files /dev/null and b/src/lib/modex/demos/c/x-demo.exe differ diff --git a/src/lib/modex/demos/c/x-demo.prj b/src/lib/modex/demos/c/x-demo.prj new file mode 100755 index 00000000..b3f307e5 Binary files /dev/null and b/src/lib/modex/demos/c/x-demo.prj differ diff --git a/src/lib/modex/demos/c/x.exe b/src/lib/modex/demos/c/x.exe new file mode 100755 index 00000000..7742d145 Binary files /dev/null and b/src/lib/modex/demos/c/x.exe differ diff --git a/src/lib/modex/demos/chardemo.exe b/src/lib/modex/demos/chardemo.exe new file mode 100755 index 00000000..4015bdf1 Binary files /dev/null and b/src/lib/modex/demos/chardemo.exe differ diff --git a/src/lib/modex/demos/pascal/test5.pas b/src/lib/modex/demos/pascal/test5.pas new file mode 100755 index 00000000..7cc56bbb --- /dev/null +++ b/src/lib/modex/demos/pascal/test5.pas @@ -0,0 +1,488 @@ +{ ModeX Turbo Pascal Demo Program } +{ Converted to Turbo Pascal by Scott Wyatt } +{ Original program written in QuickBasic by Matt Prichard } +{ Released to the Public Domain } +{ } +{ Thanks to Matt Prichard for his *EXCELLENT* ModeX Library } +{ Additional Comments by Matt Pritchard } + +Uses Crt; + +{$L modex2.obj} { This file is the external ModeX Library .OBJ } +{$F+} + + { Mode Setting Routines } + +Function SET_VGA_MODEX (Mode,MaxXpos,MaxYpos,Pages : integer) : integer; external; +Function SET_MODEX (Mode:integer) : Integer; external; + + { Graphics Primitives } + +Procedure CLEAR_VGA_SCREEN (Color:integer); external; +Procedure SET_POINT (Xpos,Ypos,Color : integer); external; +Function READ_POINT (Xpos,Ypos:integer) : integer; external; +Procedure FILL_BLOCK (Xpos1,Ypos1,Xpos2,Ypos2,Color:integer); external; +Procedure DRAW_LINE (Xpos1,Ypos1,Xpos2,Ypos2,Color:integer); external; + + { VGA DAC Routines } + +Procedure SET_DAC_REGISTER (RegNo,Red,Green,Blue:integer); external; +Procedure GET_DAC_REGISTER (RegNo,Red,Green,Blue:integer); external; + + { Page and Window Control Routines } + +Procedure SET_ACTIVE_PAGE (PageNo:integer); external; +Function GET_ACTIVE_PAGE : integer; external; +Procedure SET_DISPLAY_PAGE (PageNo:integer); external; +Function GET_DISPLAY_PAGE : integer; external; +Procedure SET_WINDOW (DisplayPage,XOffset,YOffset : integer); external; +Function GET_X_OFFSET : integer; external; +Function GET_Y_OFFSET : integer; external; +Procedure SYNC_DISPLAY; external; + + { Text Display Routines } + +Procedure GPRINTC (CharNum,Xpos,Ypos,ColorF,ColorB:integer); external; +Procedure TGPRINTC ( CharNum,Xpos,Ypos,ColorF : integer); external; +Procedure PRINT_STR (Var Text;MaxLen,Xpos,Ypos,ColorF,ColorB:integer); external; +Procedure TPRINT_STR (Var Text;MaxLen,Xpos,Ypos,ColorF:integer); external; +Procedure SET_DISPLAY_FONT (Var FontData;FontNumber:integer); external; + + { Sprite and VGA memory -> Vga memory Copy Routines } + +Procedure DRAW_BITMAP (Var Image;Xpos,Ypos,Width,Height:integer); external; +Procedure TDRAW_BITMAP (Var Image;Xpos,Ypos,Width,Height:integer); external; +Procedure COPY_PAGE (SourcePage,DestPage:integer); external; +Procedure COPY_BITMAP (SourcePage,X1,Y1,X2,Y2,DestPage,DestX1,DestY1:integer); external; + +{$F-} + + +TYPE Sprite = Record + Xpos : INTEGER; + Ypos : INTEGER; + XDir : INTEGER; + YDir : INTEGER; + Shape : INTEGER; + LastX : INTEGER; + LastY : INTEGER; + END; + + +CONST MaxShapes = 32; + Circle_16 : Array[1..16,1..16] of byte = + (( 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0), + ( 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0), + ( 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0), + ( 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0), + ( 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0), + ( 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 0), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20), + ( 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 0), + ( 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0), + ( 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0), + ( 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0), + ( 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0), + ( 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0)); + Square_16 : Array[1..16,1..16] of byte = + (( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21), + ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21)); + Diamond : Array[1..8,1..8] of byte = + (( 0, 0, 0, 22, 22, 0, 0, 0), + ( 0, 0, 22, 22, 22, 22, 0, 0), + ( 0, 22, 22, 0, 0, 22, 22, 0), + ( 22, 22, 0, 0, 0, 0, 22, 22), + ( 22, 22, 0, 0, 0, 0, 22, 22), + ( 0, 22, 22, 0, 0, 22, 22, 0), + ( 0, 0, 22, 22, 22, 22, 0, 0), + ( 0, 0, 0, 22, 22, 0, 0, 0)); + Rectangle : Array[1..8,1..3] of byte = + (( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23), + ( 23, 23, 23)); + + { Global Variables ? } + +Var + XCenter,X1,Y1,X2,Y2,Z,Colr,XChars,YChars,X,Y,N,Gap : Integer; + s : string; + s1 : Array[1..35] of Char; + ch : Char; + obj : Array[1..64] of Sprite; + ScreenX,ScreenY : Integer; + c, dc, SpriteX, SpriteY, CurrentPage, LastPage : Integer; + SetColor, SDir, PrevColor, PDir : Byte; + XView, YView : Integer; + XView_Change, YView_Change : Integer; + Right : Boolean; + Number_Of_Shapes : Byte; + + + { Error Handler - Returns to Text Mode & Displays Error } + +Procedure ERROR_OUT(s : string); + Begin + asm + mov ah,0 + mov al,3 + int 10h + end; + WriteLn(s); + Halt(0); +END; + + { Routine to Print a PASCAL string using Print_Str } + +Procedure Print_Text(s : string; X,Y,BColor,FColor : integer); +Var + s1 : Array[1..135] of Char; + i : byte; +Begin + For i := 1 to Length(s) DO + s1[i] := s[i]; + Print_Str(s1,Length(s),X,Y,BColor,FColor); +End; + + { Routine to Transparently Print a PASCAL string using TPrint_Str } + +Procedure TPrint_Text(s : string; X,Y,Color : integer); +Var + s1 : Array[1..135] of Char; + i : byte; +Begin + For i := 1 to Length(s) DO + s1[i] := s[i]; + TPrint_Str(s1,Length(s),X,Y,Color); +End; + + { Routines to show test patterns for a given mode } + +Procedure Demo_Res(Mode, Xmax, Ymax : integer); +Begin + + Str(mode,s); + If Set_ModeX(Mode) = 0 Then + Error_Out('Unable to SET_MODEX '+s); + Clear_VGA_Screen(0); + + XCenter := Xmax div 2; + X1 := 10; + Y1 := 10; + X2 := Xmax - 1; + Y2 := Ymax - 1; + + FOR Z := 0 TO 3 DO + Begin + Colr := 31 - Z * 2; + Draw_Line(X1 + Z, Y1 + Z, X2 - Z, Y1 + Z, Colr); + Draw_Line(X1 + Z, Y1 + Z, X1 + Z, Y2 - Z, Colr); + Draw_Line(X1 + Z, Y2 - Z, X2 - Z, Y2 - Z, Colr); + Draw_Line(X2 - Z, Y1 + Z, X2 - Z, Y2 - Z, Colr); + End; + + XChars := Xmax div 10; + YChars := Ymax div 10; + + FOR X := 0 TO XChars - 1 DO + Begin + TGPRINTC(48 + ((X + 1) MOD 10), X * 10 + 1, 1, 9 + ((X div 8) MOD 7)); + DRAW_LINE(X * 10 + 9, 0, X * 10 + 9, 3, 15); + End; + FOR Y := 0 TO YChars - 1 DO + Begin + TGPRINTC(48 + ((Y + 1) MOD 10), 1, Y * 10 + 1, 9 + ((Y div 10) MOD 7)); + DRAW_LINE(0, Y * 10 + 9, 3, Y * 10 + 9, 15); + End; + + { Test Line Drawing } + + FOR X := 0 TO 63 DO + Begin + N := 15 + ((X * 3) div 4); + SET_DAC_REGISTER(64 + X, N, N, N); + SET_DAC_REGISTER(128 + X, 0, N, N); + DRAW_LINE(103 - X, 60, 40 + X, 123, 64 + X); + DRAW_LINE(40, 60 + X, 103, 123 - X, 128 + X); + End; + s := 'Line Test'; + PRINT_Text(s,37,130,1,0); + + { Test Block Fills } + + Y := 60; + Gap := 0; + FOR X := 0 TO 9 DO + Begin + FILL_BLOCK(120, Y, 120 + X, Y + Gap, 64 + X); + FILL_BLOCK(140 - (15 - X), Y, 150 + X, Y + Gap, 230 + X); + FILL_BLOCK(170 - (15 - X), Y, 170, Y + Gap, 128 + X); + Y := Y + Gap + 2; + Gap := Gap + 1; + End; + s := 'Fill Test'; + Print_Text(s,110, 46, 2,0); + + { Test Pixel Write and Read } + + FOR X := 190 TO 250 DO + FOR Y := 60 TO 122 DO + SET_POINT( X, Y, X + Y + X + Y); + + s := 'Pixel Test'; + Print_Text(s,182, 130, 3,0); + + FOR X := 190 TO 250 DO + FOR Y := 60 TO 122 DO + IF READ_POINT(X, Y) <> ((X + Y + X + Y) AND 255) THEN + WriteLn('READ_PIXEL Failure'); + + { Display rest of screen } + + s := ' This is a MODE X demo '; + Print_Text(s,XCenter - (Length(s) * 4), 20, 3, 1); + s := 'Screen Resolution is by '; + X := XCenter - (Length(s) * 4); + Print_Text(s,X,30,4,0); + Str(XMax,s); + Print_Text(s, X + 8 * 21, 30, 8, 0); + Str(YMax,s); + Print_Text(s, X + 8 * 28, 30, 15, 0); + + FOR X := 0 TO 15 DO + Begin + SET_DAC_REGISTER( 230 + X, 63 - X * 4, 0, 15 + X * 3); + DRAW_LINE(30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X); + End; + s := 'Press to Continue'; + For x := 1 to length(s) DO + s1[x] := s[x]; + TPrint_Str(s1, length(s), XCenter - (26 * 4), Ymax - 18, 5); + + Ch := ReadKey; + IF Ch = #27 Then + Error_Out('Abort'); + +End; + + + { Initialize Sprites for Sprite Demo } + +Procedure Init_Sprites; +Var i : byte; +Begin + For i := 1 to 64 DO + Begin + Obj[i].XPos := Random(300)+10; + Obj[i].YPos := Random(200)+20; + Obj[i].XDir := Random(10)-5; + Obj[i].YDir := Random(10)-5; + If (Obj[i].XDir = 0) AND (Obj[i].YDir = 0) Then + Begin + Obj[i].XDir := Random(5) + 1; + Obj[i].YDir := Random(5) + 1; + End; + Obj[i].Shape := Random(4)+1; + Obj[i].LastX := obj[i].XPos; + Obj[i].LastY := obj[i].YPos; + End; +End; + +Procedure Set_Sprites(number : byte); +Var i : Byte; +Begin + For i := 1 to number DO + Begin + obj[i].LastX := obj[i].XPos; + obj[i].LastY := obj[i].YPos; + obj[i].XPos := obj[i].XPos + obj[i].XDir; + obj[i].YPos := obj[i].YPos + obj[i].YDir; + If (obj[i].XPos > 335) OR (obj[i].XPos < 5 ) Then + obj[i].XDir := -(obj[i].XDir); + If (obj[i].YPos > 220) OR (obj[i].YPos < 5) Then + obj[i].YDir := -(obj[i].YDir); + End; + For i := 1 to number DO + Case obj[i].Shape of + 1 : TDraw_Bitmap(Circle_16,obj[i].XPos,obj[i].YPos,16,16); + 2 : TDraw_Bitmap(Square_16,obj[i].XPos,obj[i].YPos,16,16); + 3 : TDraw_Bitmap(Diamond,obj[i].XPos,obj[i].YPos,8,8); + 4 : TDraw_Bitmap(Rectangle,obj[i].XPos,obj[i].YPos,3,8); + End; +End; + +Procedure Remove_Sprites(p,number : byte); +Var i : byte; +Begin + For i := 1 to number DO + Copy_Bitmap(2,obj[i].LastX,obj[i].LastY,obj[i].LastX+16,obj[i].LastY+16,p,Obj[i].LastX,Obj[i].LastY); +End; + +Procedure Page_Demo; +Begin + Number_Of_Shapes := 64; + XView_Change := 1; + YView_Change := 1; + XView := 1; + YView := 1; + Right := TRUE; + ScreenX := 360; + ScreenY := 240; + PrevColor := 0; + SetColor := 3; + SDir := 1; + PDir := 1; + Str(0,s); + + IF SET_VGA_MODEX(0, ScreenX, ScreenY, 3) = 0 THEN + ERROR_OUT('Unable to SET_VGA_MODEX' + S); + + SET_ACTIVE_PAGE(0); + CLEAR_VGA_SCREEN(0); + PRINT_TEXT('This is a Test of the Following Functions:', 10, 9, 15, 0); + DRAW_LINE( 10, 18, 350, 18, 4); + Print_Text('SET_ACTIVE_PAGE', 10, 20, 1, 0); + Print_Text('SET_DISPLAY_PAGE', 10, 30, 3,0); + Print_Text('SET_DAC_REGISTER', 10, 40, 3, 0); + Print_Text('CLEAR_VGA_SCREEN', 10, 50, 13, 0); + Print_Text('TDRAW_BITMAP', 10, 60, 14, 0); + Print_Text('COPY_PAGE', 10, 70, 3, 0); + Print_Text('COPY_BITMAP', 10, 80, 13, 0); + Print_Text('GPRINTC', 10, 90, 1, 0); + Print_Text('TGPRINTC', 10, 100, 3, 0); + Print_Text('SYNC_DISPLAY', 10, 110, 3, 0); + Print_Text('SET_WINDOW', 10, 120, 14, 0); + Print_Text('VIRTUAL SCREEN SIZES', 190, 20, 1, 0); + Print_Text(' SMOOTH SCROLLING', 190, 30, 3, 0); + Print_Text(' SPRITE ANIMATION', 190, 40, 13, 0); + Print_Text(' PAGE FLIPPING', 190, 50, 3, 0); + Print_Text(' COLOR CYCLING', 190, 60, 14, 0); + + FOR X := 0 TO 60 DO + Begin + SET_DAC_REGISTER( 50 + X, 3 + X, 0, 60 - X); + SET_DAC_REGISTER( 150 + X, 3 + X, 0, 60 - X); + End; + + c := 0; + DC := 1; + FOR X := 0 TO ScreenX div 2 DO + Begin + DRAW_LINE( ScreenX div 2 - 1, ScreenY div 4, X, ScreenY - 1, c + 50); + DRAW_LINE( ScreenX div 2, ScreenY div 4, ScreenX - X - 1, ScreenY - 1, c + 50); + c := c + DC; + IF (c = 0) OR (c = 60) THEN DC := -DC; + End; + + TPrint_Text('Press to Continue', 82, 190, 15); + TPrint_Text('<+> = Fewer Shapes <-> = More Shapes', 32, 204, 12); + COPY_PAGE( 0, 1); + COPY_PAGE( 0, 2); + + Ch := #0; + CurrentPage := 1; + LastPage := 0; + Set_Sprites(Number_Of_Shapes); + For c := 1 to 4 DO + Set_Dac_Register(19+c,63-(c*10),0,0); + + While Ch <> #27 DO + Begin + Set_Active_Page(currentpage); + Set_Sprites(Number_Of_Shapes); + If Right Then + Begin + XView := XView + XView_Change; + If (XView > 38) OR (XView < 2) Then + Begin + XView_Change := -(XView_Change); + Right := FALSE; + End; + End + Else + Begin + YView := YView + YView_Change; + If (YView > 38) OR (YView < 2) Then + Begin + YView_Change := -(YView_Change); + Right := TRUE; + End; + End; + + Set_Window(currentpage,XView,YView); + Set_Display_Page(currentpage); + Set_Dac_Register(50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor); + Set_Dac_Register(50 + SetColor, SetColor, 10, 63 - SetColor); + Set_Dac_Register(150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor); + Set_Dac_Register(150 + SetColor, 63, 63, SetColor); + SetColor := SetColor + SDir; + IF (SetColor = 60) OR (SetColor = 0) THEN SDir := -SDir; + PrevColor := PrevColor + PDir; + IF (PrevColor = 60) OR (PrevColor = 0) THEN PDir := -PDir; + Remove_Sprites(lastpage,Number_Of_Shapes); + + If Keypressed Then + Begin + Ch := ReadKey; + Case Ch of + '-' : If Number_Of_Shapes > 1 Then + Begin + c := Number_Of_Shapes; + Copy_Bitmap(2,obj[c].XPos,obj[c].YPos,obj[c].XPos+16,obj[c].YPos+16, + currentpage,obj[c].XPos,obj[c].YPos); + Dec(Number_Of_Shapes); + End; + '+' : If Number_Of_Shapes < 64 Then Inc(Number_Of_Shapes); + End; + End; + lastpage := (lastpage+1) MOD 2; + currentpage := (currentpage+1) MOD 2; + End; +END; + + { MAIN ROUTINE - Run Through Demos and Exit } + +Begin + + Randomize; + Init_Sprites; + + Demo_Res(0, 320, 200); + Demo_Res(1, 320, 400); + Demo_Res(2, 360, 200); + Demo_Res(3, 360, 400); + Demo_Res(4, 320, 240); + Demo_Res(5, 320, 480); + Demo_Res(6, 360, 240); + Demo_Res(7, 360, 480); + Page_Demo; + + asm + mov ah,0 + mov al,3 + int 10h + end; + WriteLn('THIS MODE X DEMO IS FINISHED'); + +END. \ No newline at end of file diff --git a/src/lib/modex/demos/qb45/make-lib.bat b/src/lib/modex/demos/qb45/make-lib.bat new file mode 100755 index 00000000..b04876ad --- /dev/null +++ b/src/lib/modex/demos/qb45/make-lib.bat @@ -0,0 +1,5 @@ +ECHO ... Building MODEX.QLB for QUICKBASIC 4.5 +LIB MODEX -+MODEX,, +LIB MODEX -+UTILS,, +DEL MODEX.BAK +LINK /Q MODEX+UTILS, MODEX.QLB, NUL, C:\QB45\BQLB45.LIB; diff --git a/src/lib/modex/demos/qb45/modex.bi b/src/lib/modex/demos/qb45/modex.bi new file mode 100755 index 00000000..6b1d7afe --- /dev/null +++ b/src/lib/modex/demos/qb45/modex.bi @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/src/lib/modex/demos/qb45/modex.qlb b/src/lib/modex/demos/qb45/modex.qlb new file mode 100755 index 00000000..90122c13 Binary files /dev/null and b/src/lib/modex/demos/qb45/modex.qlb differ diff --git a/src/lib/modex/demos/qb45/test6a.bas b/src/lib/modex/demos/qb45/test6a.bas new file mode 100755 index 00000000..b2487d57 --- /dev/null +++ b/src/lib/modex/demos/qb45/test6a.bas @@ -0,0 +1,561 @@ +'File: TEST6A.BAS +'Descp.: A Mode "X" demonstration for Quickbasic 4.5 +'Author: Matt Pritchard +'Date: 14 April, 1993 +' +DECLARE SUB DEMO.RES (Mode%, Xmax%, Ymax%) +DECLARE SUB ERROR.OUT (Message$) +DECLARE FUNCTION GET.KEY% () +DECLARE SUB LOAD.SHAPES () +DECLARE SUB PAGE.DEMO () +DECLARE SUB PRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%, ColorB%) +DECLARE SUB TPRINT.TEXT (Text$, Xpos%, Ypos%, ColorF%) +DEFINT A-Z + + +TYPE ShapeType + ImgData AS STRING * 512 + xWidth AS INTEGER + yWidth AS INTEGER +END TYPE + +TYPE Sprite + Xpos AS INTEGER + Ypos AS INTEGER + XDir AS INTEGER + YDir AS INTEGER + Shape AS INTEGER +END TYPE + + +CONST MaxShapes = 32 + + REM $INCLUDE: 'UTILS.BI' + REM $INCLUDE: 'MODEX.BI' + +DIM SHARED Img(32) AS ShapeType +COMMON SHARED Img() AS ShapeType + + + CALL INIT.RANDOM + + CALL LOAD.SHAPES + + CALL DEMO.RES(Mode320x200, 320, 200) + CALL DEMO.RES(Mode320x400, 320, 400) + + CALL DEMO.RES(Mode360x200, 360, 200) + CALL DEMO.RES(Mode360x400, 360, 400) + + CALL DEMO.RES(Mode320x240, 320, 240) + CALL DEMO.RES(Mode320x480, 320, 480) + + CALL DEMO.RES(Mode360x240, 360, 240) + CALL DEMO.RES(Mode360x480, 360, 480) + + CALL PAGE.DEMO + + SET.VIDEO.MODE 3 + DOS.PRINT "THIS MODE X DEMO IS FINISHED" + END + +SUB DEMO.RES (Mode, Xmax, Ymax) + + IF SET.MODEX%(Mode) = 0 THEN + ERROR.OUT "Unable to SET_MODEX" + STR$(Mode) + END IF + + XCenter = Xmax \ 2 + + X1 = 10 + Y1 = 10 + X2 = Xmax - 1 + Y2 = Ymax - 1 + + FOR Z = 0 TO 3 + Colr = 31 - Z * 2 + DRAW.LINE X1 + Z, Y1 + Z, X2 - Z, Y1 + Z, Colr + DRAW.LINE X1 + Z, Y1 + Z, X1 + Z, Y2 - Z, Colr + DRAW.LINE X1 + Z, Y2 - Z, X2 - Z, Y2 - Z, Colr + DRAW.LINE X2 - Z, Y1 + Z, X2 - Z, Y2 - Z, Colr + NEXT Z + + XChars = Xmax \ 10 + YChars = Ymax \ 10 + + FOR X = 0 TO XChars - 1 + TGPRINTC 48 + ((X + 1) MOD 10), X * 10 + 1, 1, 9 + ((X \ 8) MOD 7) + DRAW.LINE X * 10 + 9, 0, X * 10 + 9, 3, 15 + NEXT X + + FOR Y = 0 TO YChars - 1 + TGPRINTC 48 + ((Y + 1) MOD 10), 1, Y * 10 + 1, 9 + ((Y \ 10) MOD 7) + DRAW.LINE 0, Y * 10 + 9, 3, Y * 10 + 9, 15 + NEXT Y + + ' Draw Lines + + FOR X = 0 TO 63 + N = 15 + X * .75 + SET.DAC.REGISTER 64 + X, N, N, N + SET.DAC.REGISTER 128 + X, 0, N, N + + DRAW.LINE 103 - X, 60, 40 + X, 123, 64 + X + DRAW.LINE 40, 60 + X, 103, 123 - X, 128 + X + + NEXT X + TPRINT.TEXT "LINE TEST", 37, 130, c.BLUE + + Y = 60: Gap = 0 + FOR X = 0 TO 9 + FILL.BLOCK 120, Y, 120 + X, Y + Gap, 64 + X + FILL.BLOCK 140 - (15 - X), Y, 150 + X, Y + Gap, 230 + X + FILL.BLOCK 170 - (15 - X), Y, 170, Y + Gap, 128 + X + Y = Y + Gap + 2 + Gap = Gap + 1 + NEXT X + TPRINT.TEXT "FILL TEST", 110, 46, c.GREEN + + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + SET.POINT X, Y, X + Y + X + Y + NEXT Y + NEXT X + + TPRINT.TEXT "PIXEL TEST", 182, 130, c.RED + + FOR X = 190 TO 250 STEP 2 + FOR Y = 60 TO 122 STEP 2 + IF READ.POINT(X, Y) <> ((X + Y + X + Y) AND 255) THEN + ERROR.OUT "READ.PIXEL Failure" + END IF + NEXT Y + NEXT X + + + + Msg$ = " This is a MODE X demo " + PRINT.TEXT Msg$, XCenter - (LEN(Msg$) * 4), 20, c.bRED, c.BLUE + Msg$ = "Screen Resolution is by " + Xp = XCenter - (LEN(Msg$) * 4) + PRINT.TEXT Msg$, Xp, 30, c.bGREEN, c.BLACK + + PRINT.TEXT LTRIM$(STR$(Xmax)), Xp + 8 * 21, 30, c.bPURPLE, c.BLACK + PRINT.TEXT LTRIM$(STR$(Ymax)), Xp + 8 * 28, 30, c.bWHITE, c.BLACK + + FOR X = 0 TO 15 + SET.DAC.REGISTER 230 + X, 63 - X * 4, 0, 15 + X * 3 + DRAW.LINE 30 + X, Ymax - 6 - X, Xmax - 20 - X, Ymax - 6 - X, 230 + X + NEXT X + TPRINT.TEXT "Press to Continue", XCenter - (26 * 4), Ymax - 18, c.YELLOW + + X = GET.KEY% + IF X = KyESC THEN ERROR.OUT "ABORT" + +END SUB + +SUB ERROR.OUT (Message$) + + SET.VIDEO.MODE 3 + DOS.PRINT Message$ + END + +END SUB + +FUNCTION GET.KEY% + + DO + X = SCAN.KEYBOARD + LOOP UNTIL X + + GET.KEY% = X + +END FUNCTION + +SUB LOAD.SHAPES + +DIM Grid(1 TO 32, 1 TO 32) + + FOR Shape = 0 TO MaxShapes - 1 + + FOR Y = 1 TO 32 + FOR X = 1 TO 32 + Grid(X, Y) = 0 + NEXT X + NEXT Y + + Style = RANDOM.INT(6) + Colour = 1 + RANDOM.INT(15) + + SELECT CASE Style + + CASE 0: ' Solid Box + + DO + xWidth = 3 + RANDOM.INT(30) + yWidth = 3 + RANDOM.INT(30) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + CASE 1: ' Hollow Box + + DO + xWidth = 5 + RANDOM.INT(28) + yWidth = 5 + RANDOM.INT(28) + LOOP UNTIL ((xWidth * yWidth) <= 512) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + Grid(X, Y) = Colour + NEXT X + NEXT Y + + HollowX = 1 + RANDOM.INT(xWidth \ 2 - 1) + HollowY = 1 + RANDOM.INT(yWidth \ 2 - 1) + + FOR Y = HollowY + 1 TO yWidth - HollowY + FOR X = HollowX + 1 TO xWidth - HollowX + Grid(X, Y) = nil + NEXT X + NEXT Y + + CASE 2: ' Solid Diamond + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + NEXT X + NEXT Y + + + CASE 3: ' Hollow Diamond + + + xWidth = 3 + 2 * RANDOM.INT(10) + yWidth = xWidth + Centre = xWidth \ 2 + sWidth = RANDOM.INT(Centre) + + FOR Y = 0 TO Centre + FOR X = 0 TO Y + IF X + (Centre - Y) >= sWidth THEN + Grid(Centre - X + 1, Y + 1) = Colour + Grid(Centre + X + 1, Y + 1) = Colour + Grid(Centre - X + 1, yWidth - Y) = Colour + Grid(Centre + X + 1, yWidth - Y) = Colour + END IF + NEXT X + NEXT Y + + CASE 4: ' Ball + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + CASE 5: ' Ball + + + xWidth = 7 + 2 * RANDOM.INT(8) + yWidth = xWidth + Centre = 1 + xWidth \ 2 + sWidth = RANDOM.INT(xWidth) + + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + D = SQR(((Centre - X) * (Centre - X)) + ((Centre - Y) * (Centre - Y))) + IF D < Centre AND D >= sWidth THEN Grid(X, Y) = 150 + Colour * 2 + D * 3 + NEXT X + NEXT Y + + END SELECT + + Img(Shape).xWidth = xWidth + Img(Shape).yWidth = yWidth + + A$ = STRING$(xWidth * yWidth, nil) + + c = 1 + FOR Y = 1 TO yWidth + FOR X = 1 TO xWidth + MID$(A$, c, 1) = CHR$(Grid(X, Y)) + c = c + 1 + NEXT X + NEXT Y + + Img(Shape).ImgData = A$ + + + NEXT Shape + +END SUB + +SUB PAGE.DEMO + +CONST MaxSprites = 64 + +DIM Obj(MaxSprites) AS Sprite +DIM LastX(MaxSprites, 1), LastY(MaxSprites, 1) +DIM LastObjects(1) + + ScreenX = 360: ScreenY = 240 + + IF SET.VGA.MODEX%(Mode320x200, ScreenX, ScreenY, 3) = 0 THEN + ERROR.OUT "Unable to SET_VGA_MODEX" + STR$(Mode) + END IF + + SET.ACTIVE.PAGE 0 + + CLEAR.VGA.SCREEN c.BLACK + + PRINT.TEXT "This is a Test of the Following Functions:", 10, 9, c.bWHITE, c.BLACK + + DRAW.LINE 10, 18, 350, 18, c.YELLOW + PRINT.TEXT "SET_ACTIVE_PAGE", 10, 20, c.bBLUE, c.BLACK + PRINT.TEXT "SET_DISPLAY_PAGE", 10, 30, c.GREEN, c.BLACK + PRINT.TEXT "SET_DAC_REGISTER", 10, 40, c.RED, c.BLACK + PRINT.TEXT "CLEAR_VGA_SCREEN", 10, 50, c.CYAN, c.BLACK + + PRINT.TEXT "TDRAW_BITMAP", 10, 60, c.PURPLE, c.BLACK + PRINT.TEXT "COPY_PAGE", 10, 70, c.GREEN, c.BLACK + PRINT.TEXT "COPY_BITMAP", 10, 80, c.CYAN, c.BLACK + + PRINT.TEXT "GPRINTC", 10, 90, c.BLUE, c.BLACK + PRINT.TEXT "TGPRINTC", 10, 100, c.GREEN, c.BLACK + PRINT.TEXT "SET_WINDOW", 10, 110, c.RED, c.BLACK + + PRINT.TEXT "VIRTUAL SCREEN SIZES", 190, 20, c.bBLUE, c.BLACK + PRINT.TEXT " SMOOTH SCROLLING", 190, 30, c.GREEN, c.BLACK + PRINT.TEXT " SPRITE ANIMATION", 190, 40, c.CYAN, c.BLACK + PRINT.TEXT " PAGE FLIPPING", 190, 50, c.RED, c.BLACK + PRINT.TEXT " COLOR CYCLING", 190, 60, c.PURPLE, c.BLACK + + + FOR X = 0 TO 60 + SET.DAC.REGISTER 50 + X, 3 + X, 0, 60 - X + SET.DAC.REGISTER 150 + X, 3 + X, 0, 60 - X + NEXT X + + c = 0: DC = 1 + FOR X = 0 TO ScreenX \ 2 + DRAW.LINE ScreenX \ 2 - 1, ScreenY \ 4, X, ScreenY - 1, c + 50 + DRAW.LINE ScreenX \ 2, ScreenY \ 4, ScreenX - X - 1, ScreenY - 1, c + 50 + c = c + DC + IF c = 0 OR c = 60 THEN DC = -DC + NEXT X + + TPRINT.TEXT "Press to Continue", 72, 190, c.bWHITE + TPRINT.TEXT "< > = Faster < > = Slower", 72, 204, c.bGREEN + TPRINT.TEXT "< > = Fewer Shapes < > = More Shapes", 32, 218, c.bCYAN + + TGPRINTC 43, 80, 204, c.YELLOW + TGPRINTC 45, 200, 204, c.YELLOW + + TGPRINTC 25, 40, 218, c.YELLOW + TGPRINTC 24, 200, 218, c.YELLOW + + COPY.PAGE 0, 1 + COPY.PAGE 0, 2 + + FOR X = 1 TO MaxSprites + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + + Obj(X).Shape = X MOD MaxShapes + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + Obj(X).Xpos = 1 + RANDOM.INT(ScreenX - SpriteX - 2) + Obj(X).Ypos = 1 + RANDOM.INT(ScreenY - SpriteY - 2) + + LastX(X, 0) = Obj(X).Xpos + LastX(X, 1) = Obj(X).Xpos + LastY(X, 0) = Obj(X).Ypos + LastY(X, 1) = Obj(X).Ypos + NEXT X + + CurrentPage = 0 + + 'View Shift... + + ViewX = 0 + ViewY = 0 + ViewMax = 3 + ViewCnt = 0 + ViewXD = 1 + ViewYD = 1 + + SetColor = 3: SDir = 1 + PrevColor = 0: PDir = 1 + + VisObjects = MaxSprites \ 2 + LastObjects(0) = 0 + LastObjects(1) = 0 + +DRAW.LOOP: + + + SET.ACTIVE.PAGE CurrentPage + + ' Erase Old Images + + FOR X = 1 TO LastObjects(CurrentPage) + + X1 = LastX(X, CurrentPage) AND &HFFFC + Y1 = LastY(X, CurrentPage) + X2 = ((LastX(X, CurrentPage) + Img(Obj(X).Shape).xWidth)) OR 3 + Y2 = Y1 + Img(Obj(X).Shape).yWidth - 1 + + COPY.BITMAP 2, X1, Y1, X2, Y2, CurrentPage, X1, Y1 + + NEXT X + + ' Draw new images + + FOR X = 1 TO VisObjects + + SpriteX = Img(Obj(X).Shape).xWidth + SpriteY = Img(Obj(X).Shape).yWidth + + ' Move Sprite + +REDOX: + NewX = Obj(X).Xpos + Obj(X).XDir + IF NewX < 0 OR NewX + SpriteX > ScreenX THEN + Obj(X).XDir = -Obj(X).XDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOX + END IF + END IF + Obj(X).Xpos = Obj(X).Xpos + Obj(X).XDir + +REDOY: + NewY = Obj(X).Ypos + Obj(X).YDir + IF NewY < 0 OR NewY + SpriteY > ScreenY THEN + Obj(X).YDir = -Obj(X).YDir + IF RANDOM.INT(20) = 1 THEN + DO + Obj(X).XDir = RANDOM.INT(7) - 3 + Obj(X).YDir = RANDOM.INT(7) - 3 + LOOP WHILE (Obj(X).XDir = 0 AND Obj(X).YDir = 0) + GOTO REDOY + END IF + END IF + Obj(X).Ypos = Obj(X).Ypos + Obj(X).YDir + + 'Draw Sprite + + TDRAW.BITMAP Img(Obj(X).Shape), Obj(X).Xpos, Obj(X).Ypos, SpriteX, SpriteY + + LastX(X, CurrentPage) = Obj(X).Xpos + LastY(X, CurrentPage) = Obj(X).Ypos + + NEXT X + + LastObjects(CurrentPage) = VisObjects + + ' Pan Screen Back & Forth + + ViewCnt = ViewCnt + 1 + IF ViewCnt >= ViewMax THEN + ViewX = ViewX + ViewXD + IF ViewX = 0 OR ViewX = 39 THEN ViewXD = -ViewXD + IF ViewXD < 0 THEN + ViewY = ViewY + ViewYD + IF ViewY = 0 OR ViewY = 39 THEN ViewYD = -ViewYD + END IF + + SET.WINDOW CurrentPage, ViewX, ViewY + + ViewCnt = 0 + ELSE + SET.DISPLAY.PAGE CurrentPage + END IF + + ' Cycle Colors + + SET.DAC.REGISTER 50 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 50 + SetColor, SetColor, 10, 63 - SetColor + + SET.DAC.REGISTER 150 + PrevColor, 3 + PrevColor, 0, 60 - PrevColor + SET.DAC.REGISTER 150 + SetColor, 63, 63, SetColor + + SetColor = SetColor + SDir + IF SetColor = 60 OR SetColor = 0 THEN SDir = -SDir + + PrevColor = PrevColor + PDir + IF PrevColor = 60 OR PrevColor = 0 THEN PDir = -PDir + + CurrentPage = 1 - CurrentPage + + Code = SCAN.KEYBOARD + + IF Code = False THEN GOTO DRAW.LOOP + + IF Code = KyPlus THEN + IF ViewMax < 12 THEN ViewMax = ViewMax + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyMinus THEN + IF ViewMax > 1 THEN ViewMax = ViewMax - 1 + IF ViewCnt >= ViewMax THEN ViewCnt = 0 + GOTO DRAW.LOOP + END IF + + IF Code = KyUp THEN + IF VisObjects < MaxSprites THEN VisObjects = VisObjects + 1 + GOTO DRAW.LOOP + END IF + + IF Code = KyDown THEN + IF VisObjects > 1 THEN VisObjects = VisObjects - 1 + GOTO DRAW.LOOP + END IF + + +END SUB + +SUB PRINT.TEXT (Text$, Xpos, Ypos, ColorF, ColorB) + + IF LEN(Text$) = 0 THEN EXIT SUB + PRINT.STR VARSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF, ColorB + + +END SUB + +SUB TPRINT.TEXT (Text$, Xpos, Ypos, ColorF) + + IF LEN(Text$) = 0 THEN EXIT SUB + + TPRINT.STR VARSEG(Text$), SADD(Text$), LEN(Text$), Xpos, Ypos, ColorF + +END SUB + diff --git a/src/lib/modex/demos/qb45/test6a.exe b/src/lib/modex/demos/qb45/test6a.exe new file mode 100755 index 00000000..e61d0387 Binary files /dev/null and b/src/lib/modex/demos/qb45/test6a.exe differ diff --git a/src/lib/modex/demos/qb45/uasm-qb4.bat b/src/lib/modex/demos/qb45/uasm-qb4.bat new file mode 100755 index 00000000..e4aa87e0 --- /dev/null +++ b/src/lib/modex/demos/qb45/uasm-qb4.bat @@ -0,0 +1 @@ +MASM utils, utils, utils, nul; \ No newline at end of file diff --git a/src/lib/modex/demos/qb45/utils.asm b/src/lib/modex/demos/qb45/utils.asm new file mode 100755 index 00000000..811b8f8e --- /dev/null +++ b/src/lib/modex/demos/qb45/utils.asm @@ -0,0 +1,406 @@ +;======================================================= +;=== UTILS.ASM - Asm Utilities for QuickBasic/BC7 === +;======================================================= + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ==== MACROS ==== + + ; macros to PUSH and POP multiple registers + +PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + push R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + +POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + pop R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF +ENDM + + ; Macro to Clear a Register to 0 + +CLR MACRO Register + xor Register, Register ; Set Register = 0 +ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + dec Register ; Counter-- + jnz Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + dec Register ; Counter-- + jz Destination ; Jump if 0 +ENDM + + + ; ==== General Constants ==== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x4 EQU + ?x3 EQU + + +IFDEF FARSTRINGS + + EXTRN stringaddress:far + EXTRN stringlength:far + +ENDIF + + + .Data + + EVEN + +RND_Seed DW 7397, 29447, 802 +RND_Mult DW 179, 183, 182 +RND_ModV DW 32771, 32779, 32783 + +CR_LF DB 13, 10 ; the CRLF data + + .Code + +;================= +;DOS_PRINT (Text$) +;================= +; +; Prints Text Directly to DOS console w/ CR/LF +; + + PUBLIC DOS_PRINT + +DP_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + DP_Text DW ? ; Address of Text$ Descriptor +DP_Stack ENDS + + +DOS_PRINT PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @No_Print ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@No_Print: + mov AX, SEG DGROUP ; Restore DGroup + mov DS, AX + + mov DX, o CR_LF ; Get Addr of CR/LF pair + mov CX, 2 ; 2 Characters to Write + mov BX, 1 ; 1= DOS Handle for Display + + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINT ENDP + + +;================== +;DOS_PRINTS (Text$) +;================== +; +; Print Text$ Directly to DOS console +; without a trailing CR/LF +; + + PUBLIC DOS_PRINTS + +DOS_PRINTS PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + mov SI, [BP].DP_Text ; Get Addr of Text$ descriptor + +IFDEF FARSTRINGS + push SI ; Push Addr of BC7 Decriptor Ptr + call stringaddress ; Get Address + Len of string!!! + ; DX:AX = Addr CX = Len + mov DS, DX ; DS = DX = Segment of string + mov DX, AX ; DX = AX = Offset of String +ELSE + mov CX, [SI] ; put its length into CX + mov DX, [SI+02] ; now DS:DX points to the String +ENDIF + + jcxz @DPS_Exit ; Don't Print if empty + + mov BX, 1 ; 1= DOS Handle for Display + mov AH, 40h ; Write Text Function + int 21h ; Call DOS to do it + +@DPS_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +DOS_PRINTS ENDP + + +;====================== +;SET_VIDEO_MODE (Mode%) +;====================== +; +; Sets the Video Mode through the BIOS +; + + PUBLIC SET_VIDEO_MODE + +SVM_Stack STRUC + DW ?x4 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Mode DB ?,? ; Desired Video Mode +SVM_Stack ENDS + + +SET_VIDEO_MODE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR AH ; Function 0 + mov AL, [BP].SVM_Mode ; Get Mode # + + int 10H ; Change Video Modes + +@SVM_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + ret 2 ; Exit & Clean Up Stack + +SET_VIDEO_MODE ENDP + + +;============== +;SCAN_KEYBOARD% +;============== +; +; Function to scan keyboard for a pressed key +; + + PUBLIC SCAN_KEYBOARD + +SCAN_KEYBOARD PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + + mov AH, 01H ; Function #1 + int 16H ; Call Keyboard Driver + jz @SK_NO_KEY ; Exit if Zero flag set + + mov AH, 00H ; Remove Key from Buffer + int 16H ; Get Keycode in AX + + or AL, AL ; Low Byte Set (Ascii?) + jz @SK_Exit ; if not, it's a F-Key + + CLR AH ; Clear ScanCode if Ascii + jmp s @SK_Exit ; Return Key in AX + +@SK_NO_KEY: + CLR AX ; Return Nil (no Keypress) + +@SK_Exit: + cld ; Reset Direction Flag + POPx DI, SI, DS, BP ; Restore Saved Registers + ret ; Exit & Clean Up Stack + +SCAN_KEYBOARD ENDP + + +;==================== +;RANDOM_INT (MaxInt%) +;==================== +; +; Returns a pseudo-random number in the range of (0.. MaxInt-1) +; + + + PUBLIC RANDOM_INT + +RI_Stack STRUC + DW ? ; BP + DD ? ; Caller + RI_MaxVal DW ? ; Maximum Value to Return + 1 +RI_Stack ENDS + + +RANDOM_INT PROC FAR + + push BP ; Preserve Important Registers + mov BP, SP ; Set up Stack Frame + + CLR BX ; BX is the data index + CLR CX ; CX is the accumulator + +REPT 3 + mov AX, RND_Seed[BX] ; load the initial seed + mul RND_Mult[BX] ; multiply it + div RND_ModV[BX] ; and obtain the Mod value + mov RND_Seed[BX], DX ; save that for the next time + + add CX, DX ; add it into the accumulator + inc BX + inc BX ; point to the next set of values +ENDM + + mov AX, CX ; AX = Random # + CLR DX ; DX = 0 + div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder + + mov AX, DX + + pop BP ; Restore BP + ret 2 ; back to BASIC with AX holding the result + +RANDOM_INT ENDP + + +;=========== +;INIT_RANDOM +;=========== +; +; Scrambles the psuedo-random number sequence +; (XOR's the seed value with the timer) +; + + PUBLIC INIT_RANDOM + +INIT_RANDOM PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX + mov AX, ES:[046Ch] ; Get Timer Lo Word + + xor RND_Seed, AX ; Scramble 1st Seed + + ret ; Exit & Clean Up Stack + +INIT_RANDOM ENDP + + +;==================== +;INT_SQR (X%, Round%) +;==================== +; +; Returns the Integer Square Root of (X) +; Round allows the return value to be rounded to the +; nearest integer value by passing 0x80. Passing 0 +; return the Integer Portion only. The rounding amound is +; a number from 0 to 1 multiplied by 256, thus +; 0.5 * 0x100 = 0x80! +; + +ISQ_Stack STRUC + DW ?,? ; BP, DI + DD ? ; Caller + ISQ_Round DW ? ; Amount to Round Result * 256 + ISQ_X DW ? ; "X" +ISQ_Stack ENDS + + PUBLIC INT_SQR + +INT_SQR PROC FAR + + PUSHx BP, DI ; Save BP + mov BP, SP ; Set up Stack Frame + + xor AX, AX ; {xor eax,eax} + xor DX, DX ; {xor edx,edx} + mov DI, [BP].ISQ_X ; {mov edi,x} + + mov CX, 16 ; {mov cx, 32} + +@ISQ_L: + + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl DI, 1 ; {shl edi,1} + rcl DX, 1 ; {rcl edx,1} + shl AX, 1 ; {shl eax,1} + mov BX, AX ; {mov ebx,eax} + shl BX, 1 ; {shl ebx,1} + inc BX ; {inc ebx} + cmp DX, BX ; {cmp edx,ebx} + jl @ISQ_S + + sub DX, BX ; {sub edx,ebx} + inc AX ; {inc eax} + +@ISQ_S: + loop @ISQ_L + + add ax, [BP].ISQ_Round ; {add eax,$00008000} + ; {*round* result in hi word: ie. +0.5} + shr ax, 8 ; {shr eax,16} {to ax (result)} + + POPx DI, BP ; Restore Registers + ret 4 ; Exit + +INT_SQR ENDP + + +;============ +;TIMER_COUNT& +;============ +; +; Returns the current timer value as an integer/long integer +; + + + PUBLIC TIMER_COUNT + +TIMER_COUNT PROC FAR + + clr AX ; Segment = 0000 + mov ES, AX ; use ES to get at data + mov AX, ES:[046Ch] ; Get Timer Lo Word + mov DX, ES:[046Eh] ; Get Timer Hi Word + ret ; Exit & Return value in DX:AX + +TIMER_COUNT ENDP + + + END diff --git a/src/lib/modex/demos/qb45/utils.bi b/src/lib/modex/demos/qb45/utils.bi new file mode 100755 index 00000000..aeafeef4 --- /dev/null +++ b/src/lib/modex/demos/qb45/utils.bi @@ -0,0 +1,51 @@ + + ' Misc Constants + +CONST True = -1, False = 0, nil = 0 + + ' Keyboard Codes: Extended + +CONST KyF1 = &H3B00, KyF2 = &H3C00, KyF3 = &H3D00, KyF4 = &H3E00, KyF5 = &H3F00 +CONST KyF6 = &H4000, KyF7 = &H4100, KyF8 = &H4200, KyF9 = &H4300, KyF10 = &H4400 + +CONST KyUp = &H4800, KyLeft = &H4B00, KyRight = &H4D00, KyDown = &H5000 +CONST KySLeft = &HCB00, KySRight = &HCD00, KySUp = &HC800, KySDown = &HD000 + +CONST KyHome = &H4700, KyPgUp = &H4900, KyEnd = &H4F00, KyPgDn = &H5100 +CONST KySHome = &HC700, KySPgUp = &HC900, KySEnd = &HCF00, KySPgDn = &HD100 + +CONST KyIns = &H5200, KyDel = &H5300, KyRvsTab = &H8F00 +CONST KySIns = &HC200, KySDel = &HC300 + +CONST KyAltA = &H1E00, KyAltB = &H3000, KyAltC = &H2E00, KyAltD = &H2000 +CONST KyAltE = &H1200, KyAltF = &H2100, KyAltG = &H2200, KyAltH = &H2300 +CONST KyAltI = &H1700, KyAltJ = &H2400, KyAltK = &H2500, KyAltL = &H2600 +CONST KyAltM = &H3200, KyAltN = &H3100, KyAltO = &H1800, KyAltP = &H1900 +CONST KyAltQ = &H1000, KyAltR = &H1300, KyAltS = &H1F00, KyAltT = &H1400 +CONST KyAltU = &H1600, KyAltV = &H2F00, KyAltW = &H1100, KyAltX = &H2D00 +CONST KyAltY = &H1500, KyAltZ = &H2C00 + + ' Keyboard Codes: Ascii + +CONST KyBS = 8, KyTab = 9, KyCR = 13, KyESC = &H1B, KyClr = &H7F +CONST KyPlus = 45, KyMinus = 43 + + ' Color Constants + +CONST c.BLACK = 0, c.BLUE = 1, c.GREEN = 2, c.CYAN = 3 +CONST c.RED = 4, c.PURPLE = 5, c.BROWN = 6, c.WHITE = 7 +CONST c.GREY = 8, c.bBLUE = 9, c.bGREEN = 10, c.bCYAN = 11 +CONST c.bRED = 12, c.bPURPLE = 13, c.YELLOW = 14, c.bWHITE = 15 +CONST c.BRIGHT = 8 + + ' From UTILS.ASM + +DECLARE SUB DOS.PRINT ALIAS "DOS_PRINT" (Text$) +DECLARE SUB DOS.PRINTS ALIAS "DOS_PRINTS" (Text$) +DECLARE SUB SET.VIDEO.MODE ALIAS "SET_VIDEO_MODE" (BYVAL Mode%) +DECLARE FUNCTION SCAN.KEYBOARD% ALIAS "SCAN_KEYBOARD" +DECLARE FUNCTION RANDOM.INT ALIAS "RANDOM_INT" (BYVAL MaxInt%) +DECLARE SUB INIT.RANDOM ALIAS "INIT_RANDOM" +DECLARE FUNCTION TIMER.COUNT& ALIAS "TIMER_COUNT" +DECLARE FUNCTION INT.SQR ALIAS "INT_SQR" (BYVAL X%, BYVAL Round%) + diff --git a/src/lib/modex/demos/rom_8x8.fnt b/src/lib/modex/demos/rom_8x8.fnt new file mode 100755 index 00000000..708a4f92 Binary files /dev/null and b/src/lib/modex/demos/rom_8x8.fnt differ diff --git a/src/lib/modex/demos/spaceage.fnt b/src/lib/modex/demos/spaceage.fnt new file mode 100755 index 00000000..029bae4e Binary files /dev/null and b/src/lib/modex/demos/spaceage.fnt differ diff --git a/src/lib/modex/demos/system.fnt b/src/lib/modex/demos/system.fnt new file mode 100755 index 00000000..9a1965eb Binary files /dev/null and b/src/lib/modex/demos/system.fnt differ diff --git a/src/lib/modex/demos/test6.exe b/src/lib/modex/demos/test6.exe new file mode 100755 index 00000000..5682c475 Binary files /dev/null and b/src/lib/modex/demos/test6.exe differ diff --git a/src/lib/modex/fontedit/charsets.cs b/src/lib/modex/fontedit/charsets.cs new file mode 100755 index 00000000..97fe608f Binary files /dev/null and b/src/lib/modex/fontedit/charsets.cs differ diff --git a/src/lib/modex/fontedit/csedit.doc b/src/lib/modex/fontedit/csedit.doc new file mode 100755 index 00000000..97ff07e0 --- /dev/null +++ b/src/lib/modex/fontedit/csedit.doc @@ -0,0 +1,196 @@ + +CSEDIT - A Simple Font Editor by Matt Pritchard + + +CSEDIT is distributed with MODEXnnn.ZIP, the general purpose MODE X +Library for VGA Graphics. + +WHAT YOU NEED TO RUN CSEDIT: + + * A Vga Monitor + * A Microsoft Compatible Mouse + + A Mouse is most definitely required, as the keyboard is used for + nothing except entering file names. + +FILES NEEDED IN THE CURRENT DIRECTORY: + + CSEDIT.EXE - The Font Editor Program + CHARSETS.CS - The Font Editor's Internal Fonts + PALETTE.CS - The Font Editor's Palette + MOUSEIMG.CS - The Font Editor's Mouse Pointer + +SAMPLE FONT FILE THAT SHOULD BE INCLUDED: + + SYSTEM.FNT - The Font used by CSEDIT.EXE + INVERSE.FNT - An Inverted version of SYSTEM.FNT + SPACEAGE.FNT - A Futuristic, Tech style font + ROM_8X8.FNT - The Lower 128 characters from the VGA BIOS Rom + +WHAT IT EDITS: + + 8 by 8 character fonts, 128 characters at a time. 2 fonts at a time. + +HOW IT WORKS/FEATURES: + + CSEDIT allows the user to edit 2 different font groups at a time, + which may be loaded and saved separately. + + A enlarged character grid allows the user to edit individual pixels + on a selected character. + + The Following operations can be performed on a single character or + simultaneously on a selected block of characters. + + * Shift the selected character(s) in any direction + with or without clipping at the edges. + * Vertically Flip the selected character(s) + * Horizontally Flip the selected character(s) + * Rotate the selected character(s) 90 Degrees Clockwise + * Rotate the selected character(s) 90 Degrees Counterclockwise + * Clear the selected character(s) + * Invert the selected character(s) + * XOR the selected character(s) with other character(s) + * AND the selected character(s) with other character(s) + * OR the selected character(s) with other character(s) + * Copy the selected character(s) to another position or font. + + An UNDO feature allows the reversal of the most recent operation. + +DESCRIPTION OF OBJECTS/FEATURES FROM THE TOP DOWN: + + Character Grid: (RED) Box in Upper Left corner of screen. This is + where you edit an individual character. The Left Button sets the + pixel the mouse pointer is on, while the Right Button clears that + pixel. + + Scroll Buttons: The Four Scroll Buttons are labeled with directional + arrows, and arranged in a diamond pattern. Left Clicking on a + directional button will scroll the currently selected character + in that direction, with the pixels on the edge rolling off and + appearing on the other size. Right Clicking will prevent the + pixels from rolling to the other side. + + Vertical Flip Button: + Horizontal Flip Button: Clicking these buttons will flip the pattern + of the currently selected character(s) around the indicated axis. + i.e. the top row will be swapped with the bottom row, etc. or the + left row column will be swapped with right column, etc. + depending upon which button you push. + + Invert Button: Clicking this button causes all pixels in the selected + character(s) to flip flop between on and off. + + Clear Button: Clicking this button erases the selected characters + + Rotate Buttons: Clicking these buttons will rotate the pattern in the + selected character(s) 90 degrees in the indicated direction. + + XOR Button: Clicking this button will let you XOR the currently + selected character(s) with other character(s) in either font. + The Button will turn RED, indicating that it is waiting for + you to click on the desired character (or upper left corner + of the desired block of characters) in either the Red or Green + Character Set Displays. Clicking anywhere else will abort this + process without doing anything. If you click on (any of) the + selected character(s) the operation is aborted. If a block is + selected and the character you click on is in a position where + it can't represent the upper left corner of a block of the same + size, then the operation is not performed. + + AND Button & OR Button: These buttons work just like the XOR Button + except that the Binary operation performed is either an AND or OR + depending upon which button you have selected. + + COPY Button: This button lets you copy a character or selected block + of characters to another area in the current font or the other + font. After clicking, the button turns RED and works much like + the XOR Button. Clicking on a valid position in either font + window will copy the selected character(s) to that location. + + MODE Button: Clicking this button toggles the editor between BLOCK + mode and CHARACTER mode. The current mode is displayed on a plate + at the top of the screen, just to the right of the enlarged + character grid. In character mode the plate will read "CHAR" and + the currently selected character is displayed just to the right + of the plate. In Block mode the plate will read "BLOCK" and the + enlarged character grid is disabled. + + UNDO Button: Clicking this Button will UNDO or reverse the effects of + the most recent operation. + + QUIT Button: Clicking this button will return you to DOS. Any loaded + fonts are not saved, and no confirmation is given. + + + GREEN FONT AREA: This area displays one of the current fonts which + can be edited. The characters are display in order from #0 to #127 + from the upper left, going right, then down. The Font Box is 32 + characters wide and 4 characters Tall. When the editor is in + character mode, just point at and Left Click on the character you + wish to edit and a Cyan box will appear around that character. + + * If you Right Click on a character, the last current character, + which will still appear in the enlarged character grid, will be + copied onto the character you pointed at, replacing it. This is + a shortcut for copying characters: You can hold the right button + down an fill in a large area with a single character pattern. + When the editor is in Block Mode, you select an area by clicking + on any corner of the desired block. Then drag the mouse to the + opposite corner while holding down the left button. A Cyan Box + will stretch to surround the selected block of characters. + + GREEN FONT FILE NAME BOX: This Text Box is used to enter the name + of a font file to load or the name to save the current Green font + as. Just click on the Box, and it will change color and a + flashing cursor will appear. Now you type in a filename or edit + the existing filename. Press or click outside the text + box to end editing. + + GREEN FONT LOAD BUTTON: Clicking this button will load the font file + that is named in the Green File name box. If no name is given or + no such file exists, then nothing will be loaded. + + GREEN FONT SAVE BUTTON: Clicking this button will save the current + font in the Green Font Area under the name given in the File Name + Box. If a Valid name is not provided, nothing will be saved. + + RED FONT AREA: This is just the same as the GREEN FONT AREA; providing + you with the ability to copy and edit between multiple fonts. + + RED FONT FILE NAME BOX: This works just like the GREEN FONT FILE + NAME BOX. + + RED FONT LOAD BUTTON: This works just like the GREEN FONT LOAD BUTTON. + + RED FONT SAVE BUTTON: This works just like the GREEN FONT SAVE BUTTON. + + Message Bar: At the very bottom of the screen, this Bar will display + information and messages for various functions. + + +FONT FILE FORMAT: + + BINARY Image, in order of character. The format is identical to that + used by the VGA ROM. The Files will be exactly 1024 (128 * 8) bytes + long. + + CHARACTER: 8 Bytes + + FONT: Array (0 to 127) of CHARACTER + + +COMMENTS, QUESTIONS, BUG REPORTS, etc: + + Send the to the Author: Matt Pritchard + + Through the 80xxx Fidonet Echo or + + Matt Pritchard + P.O. Box 140264 + Irving, TX 75014 + +CREDITS: + + This Font Editor was written in QuickBASIC 4.5 + diff --git a/src/lib/modex/fontedit/csedit.exe b/src/lib/modex/fontedit/csedit.exe new file mode 100755 index 00000000..58b07325 Binary files /dev/null and b/src/lib/modex/fontedit/csedit.exe differ diff --git a/src/lib/modex/fontedit/inverse.fnt b/src/lib/modex/fontedit/inverse.fnt new file mode 100755 index 00000000..5901c517 Binary files /dev/null and b/src/lib/modex/fontedit/inverse.fnt differ diff --git a/src/lib/modex/fontedit/mouseimg.cs b/src/lib/modex/fontedit/mouseimg.cs new file mode 100755 index 00000000..101e2084 Binary files /dev/null and b/src/lib/modex/fontedit/mouseimg.cs differ diff --git a/src/lib/modex/fontedit/palette.cs b/src/lib/modex/fontedit/palette.cs new file mode 100755 index 00000000..09c5549e Binary files /dev/null and b/src/lib/modex/fontedit/palette.cs differ diff --git a/src/lib/modex/fontedit/rom_8x8.fnt b/src/lib/modex/fontedit/rom_8x8.fnt new file mode 100755 index 00000000..708a4f92 Binary files /dev/null and b/src/lib/modex/fontedit/rom_8x8.fnt differ diff --git a/src/lib/modex/fontedit/spaceage.fnt b/src/lib/modex/fontedit/spaceage.fnt new file mode 100755 index 00000000..029bae4e Binary files /dev/null and b/src/lib/modex/fontedit/spaceage.fnt differ diff --git a/src/lib/modex/fontedit/system.fnt b/src/lib/modex/fontedit/system.fnt new file mode 100755 index 00000000..9a1965eb Binary files /dev/null and b/src/lib/modex/fontedit/system.fnt differ diff --git a/src/lib/modex/makefile b/src/lib/modex/makefile new file mode 100755 index 00000000..fdf9d91c --- /dev/null +++ b/src/lib/modex/makefile @@ -0,0 +1,30 @@ +!ifdef __LINUX__ +REMOVECOMMAND=rm -f +COPYCOMMAND=cp -f +DIRSEP=/ +OBJ=o +!else +REMOVECOMMAND=del +COPYCOMMAND=copy /y +DIRSEP=\ +OBJ=obj +!endif + +CFLAGS=-d2 -0 -mc + +all: x_demo.exe + +x_demo.exe: x_demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ) + wcl $(CFLAGS) x_demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ) +x_demo.$(OBJ): x_demo.c + wcl -c $(CFLAGS) x_demo.c + +c_utils.$(OBJ): c_utils.asm + wcl -c $(CFLAGS) c_utils.asm +modex.$(OBJ): modex.asm + wcl -c $(CFLAGS) modex.asm + +clean: .symbolic + @$(REMOVECOMMAND) x-demo.exe + @$(REMOVECOMMAND) *.$(OBJ) + @$(REMOVECOMMAND) *.err diff --git a/src/lib/modex/mode-x.txt b/src/lib/modex/mode-x.txt new file mode 100755 index 00000000..4e18d962 --- /dev/null +++ b/src/lib/modex/mode-x.txt @@ -0,0 +1,44 @@ +The following is a FAQ (Frequently Asked Question) summary of +information and assembly routines for Mode "X" Graphics. + +An overview of Mode "X" for the VGA Adaptor: + +1) Mode "X" is a 256 color graphics mode that is available on *ANY* VGA +card with the minimum of 256K video RAM. It is capable of providing +higher resoultions than the only "Official" 256 color mode, mode 13h. +(In quickbasic that is mode 13) + +2) Mode "X" comes in 8 different flavors: 320 or 360 pixels +horizontally, and 200, 240, 400, and 480 pixels vertically. + +3) Since mode X is not supported by the VGA BIOS, there is no built in +support for it. A program must provide its own routines for *ALL* +operations in Mode "X", including setting up the video mode. + +4) Unlike Mode 13h, which has one display page, Mode "X" allows from 1 +to 4 video pages, depending upon the resoultion selected. The reason +that Mode 13h has but one page is that it activates a VGA hardware +feature known as CHAIN4, which prevents access to all but 64K of VGA's +video RAM. CHAIN4 is what provides mode 13h's linear addres space. + +5) Unlike Mode 13h, where each 256 color (1-byte) pixel has a unique +address in the E000: segement, in Mode X there are Four (4) Pixels +at each address in E000: segment. The VGA's control registers allow you +to control which of the 4 pixels is currently available at an address. + +6) It is possible to use the VGA's control registers to operate on 2 or +more of the Pixels at the same address at the same time. The CPU can +write one color value, and set up to 4 pixels with that value at the +same time. + +7) Video RAM that is not being used for the current screen display can +be used to store images and patterns. These images and patterns can be +copied to other parts of the Video RAM 4 bytes (32 bits) at a time, +which is much faster than the 8 bits (1 byte) at time that is possible +over the ISA BUS. (16 Bit BUS operations can produce erroneous results) + +If anything is unclear, inadequate, or you just plain want to know more +or have other specific questions, please send me a message. + + +-Matt Pritchard diff --git a/src/lib/modex/modex.asm b/src/lib/modex/modex.asm new file mode 100755 index 00000000..f2b1b512 --- /dev/null +++ b/src/lib/modex/modex.asm @@ -0,0 +1,3505 @@ +;======================================================== +; MODEX.ASM - A Complete Mode X Library +; +; Version 1.04 Release, 3 May 1993, By Matt Pritchard +; With considerable input from Michael Abrash +; +; The following information is donated to the public domain in +; the hopes that save other programmers much frustration. +; +; If you do use this code in a product, it would be nice if +; you include a line like "Mode X routines by Matt Pritchard" +; in the credits. +; +; ========================================================= +; +; All of this code is designed to be assembled with MASM 5.10a +; but TASM 3.0 could be used as well. +; +; The routines contained are designed for use in a MEDIUM model +; program. All Routines are FAR, and is assumed that a DGROUP +; data segment exists and that DS will point to it on entry. +; +; For all routines, the AX, BX, CX, DX, ES and FLAGS registers +; will not be preserved, while the DS, BP, SI and DI registers +; will be preserved. +; +; Unless specifically noted, All Parameters are assumed to be +; "PASSED BY VALUE". That is, the actual value is placed on +; the stack. When a reference is passed it is assumed to be +; a near pointer to a variable in the DGROUP segment. +; +; Routines that return a single 16-Bit integer value will +; return that value in the AX register. +; +; This code will *NOT* run on an 8086/8088 because 80286+ +; specific instructions are used. If you have an 8088/86 +; and VGA, you can buy an 80386-40 motherboard for about +; $160 and move into the 90's. +; +; This code is reasonably optimized: Most drawing loops have +; been unrolled once and memory references are minimized by +; keeping stuff in registers when possible. +; +; Error Trapping varies by Routine. No Clipping is performed +; so the caller should verify that all coordinates are valid. +; +; Several Macros are used to simplify common 2 or 3 instruction +; sequences. Several Single letter Text Constants also +; simplify common assembler expressions like "WORD PTR". +; +; ------------------ Mode X Variations ------------------ +; +; Mode # Screen Size Max Pages Aspect Ratio (X:Y) +; +; 0 320 x 200 4 Pages 1.2:1 +; 1 320 x 400 2 Pages 2.4:1 +; 2 360 x 200 3 Pages 1.35:1 +; 3 360 x 400 1 Page 2.7:1 +; 4 320 x 240 3 Pages 1:1 +; 5 320 x 480 1 Page 2:1 +; 6 360 x 240 3 Pages 1.125:1 +; 7 360 x 480 1 Page 2.25:1 +; +; -------------------- The Legal Stuff ------------------ +; +; No warranty, either written or implied, is made as to +; the accuracy and usability of this code product. Use +; at your own risk. Batteries not included. Pepperoni +; and extra cheese available for an additional charge. +; +; ----------------------- The Author -------------------- +; +; Matt Pritchard is a paid programmer who'd rather be +; writing games. He can be reached at: P.O. Box 140264, +; Irving, TX 75014 USA. Michael Abrash is a living +; god, who now works for Bill Gates (Microsoft). +; +; -------------------- Revision History ----------------- +; 4-12-93: v1.02 - SET_POINT & READ_POINT now saves DI +; SET_MODEX now saves SI +; 5-3-93: v1.04 - added LOAD_DAC_REGISTERS and +; READ_DAC_REGISTERS. Expanded CLR Macro +; to handle multiple registers +; + + PAGE 255, 132 + + .MODEL Huge + ;.286 + + ; ===== MACROS ===== + + ; Macro to OUT a 16 bit value to an I/O port + +OUT_16 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AX not setup + MOV AX, Value ; then Get Data Value + ENDIF + OUT DX, AX ; Set I/O Register(s) +ENDM + + ; Macro to OUT a 8 bit value to an I/O Port + +OUT_8 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AL not Setup + MOV AL, Value ; then Get Data Value + ENDIF + OUT DX, AL ; Set I/O Register +ENDM + + ; macros to PUSH and POP multiple registers + +; PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 +; IFNB +; PUSH R1 ; Save R1 +; PUSHx R2, R3, R4, R5, R6, R7, R8 +; ENDIF +; ENDM +; +; POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 +; IFNB +; POP R1 ; Restore R1 +; POPx R2, R3, R4, R5, R6, R7, R8 +; ENDIF +; ENDM + + ; Macro to Clear Registers to 0 + +; CLR MACRO Register, R2, R3, R4;, R5, R6 +; IFNB +; XOR Register, Register ; Set Register = 0 +; CLR R2, R3, R4;, R5, R6 +; ENDIF +; ENDM + + ; Macros to Decrement Counter & Jump on Condition + +LOOPx MACRO Register, Destination + DEC Register ; Counter-- + JNZ Destination ; Jump if not 0 +ENDM + +LOOPjz MACRO Register, Destination + DEC Register ; Counter-- + JZ Destination ; Jump if 0 +ENDM + + + ; ===== General Constants ===== + + False EQU 0 + True EQU -1 + nil EQU 0 + + b EQU BYTE PTR + w EQU WORD PTR + d EQU DWORD PTR + o EQU OFFSET + f EQU FAR PTR + s EQU SHORT + ?x1 EQU + + ; ===== VGA Register Values ===== + + VGA_Segment EQU 0A000h ; Vga Memory Segment + + ATTRIB_Ctrl EQU 03C0h ; VGA Attribute Controller + GC_Index EQU 03CEh ; VGA Graphics Controller + SC_Index EQU 03C4h ; VGA Sequencer Controller + SC_Data EQU 03C5h ; VGA Sequencer Data Port + CRTC_Index EQU 03D4h ; VGA CRT Controller + CRTC_Data EQU 03D5h ; VGA CRT Controller Data + MISC_OUTPUT EQU 03C2h ; VGA Misc Register + INPUT_1 EQU 03DAh ; Input Status #1 Register + + DAC_WRITE_ADDR EQU 03C8h ; VGA DAC Write Addr Register + DAC_READ_ADDR EQU 03C7h ; VGA DAC Read Addr Register + PEL_DATA_REG EQU 03C9h ; VGA DAC/PEL data Register R/W + + PIXEL_PAN_REG EQU 033h ; Attrib Index: Pixel Pan Reg + MAP_MASK EQU 002h ; Sequ Index: Write Map Mask reg + READ_MAP EQU 004h ; GC Index: Read Map Register + START_DISP_HI EQU 00Ch ; CRTC Index: Display Start Hi + START_DISP_LO EQU 00Dh ; CRTC Index: Display Start Lo + + MAP_MASK_PLANE1 EQU 00102h ; Map Register + Plane 1 + MAP_MASK_PLANE2 EQU 01102h ; Map Register + Plane 1 + ALL_PLANES_ON EQU 00F02h ; Map Register + All Bit Planes + + CHAIN4_OFF EQU 00604h ; Chain 4 mode Off + ASYNC_RESET EQU 00100h ; (A)synchronous Reset + SEQU_RESTART EQU 00300h ; Sequencer Restart + + LATCHES_ON EQU 00008h ; Bit Mask + Data from Latches + LATCHES_OFF EQU 0FF08h ; Bit Mask + Data from CPU + + VERT_RETRACE EQU 08h ; INPUT_1: Vertical Retrace Bit + PLANE_BITS EQU 03h ; Bits 0-1 of Xpos = Plane # + ALL_PLANES EQU 0Fh ; All Bit Planes Selected + CHAR_BITS EQU 0Fh ; Bits 0-3 of Character Data + + GET_CHAR_PTR EQU 01130h ; VGA BIOS Func: Get Char Set + ROM_8x8_Lo EQU 03h ; ROM 8x8 Char Set Lo Pointer + ROM_8x8_Hi EQU 04h ; ROM 8x8 Char Set Hi Pointer + + ; Constants Specific for these routines + + NUM_MODES EQU 8 ; # of Mode X Variations + + ; Specific Mode Data Table format... + +Mode_Data_Table STRUC + M_MiscR DB ? ; Value of MISC_OUTPUT register + M_Pages DB ? ; Maximum Possible # of pages + M_XSize DW ? ; X Size Displayed on screen + M_YSize DW ? ; Y Size Displayed on screen + M_XMax DW ? ; Maximum Possible X Size + M_YMax DW ? ; Maximum Possible Y Size + M_CRTC DW ? ; Table of CRTC register values +Mode_Data_Table ENDS + + ; ===== DGROUP STORAGE NEEDED (42 BYTES) ===== + + .DATA? + +SCREEN_WIDTH DW 0 ; Width of a line in Bytes +SCREEN_HEIGHT DW 0 ; Vertical Height in Pixels + +LAST_PAGE DW 0 ; # of Display Pages +PAGE_ADDR DW 4 DUP (0) ; Offsets to start of each page + +PAGE_SIZE DW 0 ; Size of Page in Addr Bytes + +DISPLAY_PAGE DW 0 ; Page # currently displayed +ACTIVE_PAGE DW 0 ; Page # currently active + +CURRENT_PAGE DW 0 ; Offset of current Page +CURRENT_SEGMENT DW 0 ; Segment of VGA memory + +CURRENT_XOFFSET DW 0 ; Current Display X Offset +CURRENT_YOFFSET DW 0 ; Current Display Y Offset + +CURRENT_MOFFSET DW 0 ; Current Start Offset + +MAX_XOFFSET DW 0 ; Current Display X Offset +MAX_YOFFSET DW 0 ; Current Display Y Offset + +CHARSET_LOW DW 0, 0 ; Far Ptr to Char Set: 0-127 +CHARSET_HI DW 0, 0 ; Far Ptr to Char Set: 128-255 + + .CODE + + ; ===== DATA TABLES ===== + + ; Data Tables, Put in Code Segment for Easy Access + ; (Like when all the other Segment Registers are in + ; use!!) and reduced DGROUP requirements... + + ; Bit Mask Tables for Left/Right/Character Masks + +Left_Clip_Mask DB 0FH, 0EH, 0CH, 08H + +Right_Clip_Mask DB 01H, 03H, 07H, 0FH + + ; Bit Patterns for converting character fonts + +Char_Plane_Data DB 00H,08H,04H,0CH,02H,0AH,06H,0EH + DB 01H,09H,05H,0DH,03H,0BH,07H,0FH + + ; CRTC Register Values for Various Configurations + +MODE_Single_Line: ; CRTC Setup Data for 400/480 Line modes + DW 04009H ; Cell Height (1 Scan Line) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 400/480 Line Mode + +MODE_Double_Line: ; CRTC Setup Data for 200/240 Line modes + DW 04109H ; Cell Height (2 Scan Lines) + DW 00014H ; Dword Mode off + DW 0E317H ; turn on Byte Mode + DW nil ; End of CRTC Data for 200/240 Line Mode + +MODE_320_Wide: ; CRTC Setup Data for 320 Horz Pixels + DW 05F00H ; Horz total + DW 04F01H ; Horz Displayed + DW 05002H ; Start Horz Blanking + DW 08203H ; End Horz Blanking + DW 05404H ; Start H Sync + DW 08005H ; End H Sync + DW nil ; End of CRTC Data for 320 Horz pixels + +MODE_360_Wide: ; CRTC Setup Data for 360 Horz Pixels + DW 06B00H ; Horz total + DW 05901H ; Horz Displayed + DW 05A02H ; Start Horz Blanking + DW 08E03H ; End Horz Blanking + DW 05E04H ; Start H Sync + DW 08A05H ; End H Sync + DW nil ; End of CRTC Data for 360 Horz pixels + +MODE_200_Tall: +MODE_400_Tall: ; CRTC Setup Data for 200/400 Line modes + DW 0BF06H ; Vertical Total + DW 01F07H ; Overflow + DW 09C10H ; V Sync Start + DW 08E11H ; V Sync End/Prot Cr0 Cr7 + DW 08F12H ; Vertical Displayed + DW 09615H ; V Blank Start + DW 0B916H ; V Blank End + DW nil ; End of CRTC Data for 200/400 Lines + +MODE_240_Tall: +MODE_480_Tall: ; CRTC Setup Data for 240/480 Line modes + DW 00D06H ; Vertical Total + DW 03E07H ; Overflow + DW 0EA10H ; V Sync Start + DW 08C11H ; V Sync End/Prot Cr0 Cr7 + DW 0DF12H ; Vertical Displayed + DW 0E715H ; V Blank Start + DW 00616H ; V Blank End + DW nil ; End of CRTC Data for 240/480 Lines + + ; Table of Display Mode Tables + +MODE_TABLE: + DW o MODE_320x200, o MODE_320x400 + DW o MODE_360x200, o MODE_360x400 + DW o MODE_320x240, o MODE_320x480 + DW o MODE_360x240, o MODE_360x480 + + ; Table of Display Mode Components + +MODE_320x200: ; Data for 320 by 200 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 4 ; Maximum of 4 Pages + DW 320, 200 ; Displayed Pixels (X,Y) + DW 1302, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_320x400: ; Data for 320 by 400 Pixels + + DB 063h ; 400 scan Lines & 25 Mhz Clock + DB 2 ; Maximum of 2 Pages + DW 320, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_400_Tall + DW o MODE_Single_Line, nil + +MODE_360x240: ; Data for 360 by 240 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 240 ; Displayed Pixels X,Y + DW 1092, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_240_Tall + DW o MODE_Double_Line , nil + +MODE_360x480: ; Data for 360 by 480 Pixels + + DB 0E7h ; 480 scan Lines & 28 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 360, 480 ; Displayed Pixels X,Y + DW 544, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, o MODE_480_Tall + DW o MODE_Single_Line , nil + +MODE_320x240: ; Data for 320 by 240 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 320, 240 ; Displayed Pixels X,Y + DW 1088, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_Wide, o MODE_240_Tall + DW o MODE_Double_Line, nil + +MODE_320x480: ; Data for 320 by 480 Pixels + + DB 0E3h ; 480 scan Lines & 25 Mhz Clock + DB 1 ; Only 1 Page Possible + DW 320, 480 ; Displayed Pixels X,Y + DW 540, 818 ; Max Possible X and Y Sizes + + DW o MODE_320_WIDE, o MODE_480_Tall + DW o MODE_Single_Line, nil + +MODE_360x200: ; Data for 360 by 200 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 3 ; Maximum of 3 Pages + DW 360, 200 ; Displayed Pixels (X,Y) + DW 1302, 728 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_200_Tall + DW o MODE_Double_Line, nil + +MODE_360x400: ; Data for 360 by 400 Pixels + + DB 067h ; 400 scan Lines & 28 Mhz Clock + DB 1 ; Maximum of 1 Pages + DW 360, 400 ; Displayed Pixels X,Y + DW 648, 816 ; Max Possible X and Y Sizes + + DW o MODE_360_Wide, MODE_400_Tall + DW o MODE_Single_Line, nil + + + ; ===== MODE X SETUP ROUTINES ===== + +;====================================================== +;SET_VGA_MODEX% (ModeType%, MaxXPos%, MaxYpos%, Pages%) +;====================================================== +; +; Sets Up the specified version of Mode X. Allows for +; the setup of multiple video pages, and a virtual +; screen which can be larger than the displayed screen +; (which can then be scrolled a pixel at a time) +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; +; 0 = 320 x 200, 4 Pages max, 1.2:1 Aspect Ratio +; 1 = 320 x 400, 2 Pages max, 2.4:1 Aspect Ratio +; 2 = 360 x 200, 3 Pages max, 1.35:1 Aspect Ratio +; 3 = 360 x 400, 1 Page max, 2.7:1 Aspect Ratio +; 4 = 320 x 240, 3 Pages max, 1:1 Aspect Ratio +; 5 = 320 x 480, 1 Page max, 2:1 Aspect Ratio +; 6 = 360 x 240, 3 Pages max, 1.125:1 Aspect Ratio +; 7 = 360 x 480, 1 Page max, 2.25:1 Aspect Ratio +; +; MaxXpos = The Desired Virtual Screen Width +; MaxYpos = The Desired Virtual Screen Height +; Pages = The Desired # of Video Pages +; +; EXIT: AX = Success Flag: >0 = Failure / 0 = Success +; + +SVM_STACK STRUC + SVM_Table DW ? ; Offset of Mode Info Table + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DD ? ; Caller + SVM_Pages DW ? ; # of Screen Pages desired + SVM_Ysize DW ? ; Vertical Screen Size Desired + SVM_Xsize DW ? ; Horizontal Screen Size Desired + SVM_Mode DW ? ; Display Resolution Desired +SVM_STACK ENDS + + PUBLIC SET_VGA_MODEX + +SET_VGA_MODEX PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 2 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + ; Check Legality of Mode Request.... + + MOV BX, [BP].SVM_Mode ; Get Requested Mode # + CMP BX, NUM_MODES ; Is it 0..7? + JAE @SVM_BadModeSetup1 ; If Not, Error out + + SHL BX, 1 ; Scale BX + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + MOV [BP].SVM_Table, SI ; Save ptr for later use + + ; Check # of Requested Display Pages + + MOV CX, [BP].SVM_Pages ; Get # of Requested Pages + ;CLR CH ; Set Hi Word = 0! + mov ch,0 ; Set Hi Word = 0! + CMP CL, CS:[SI].M_Pages ; Check # Pages for mode + JA @SVM_BadModeSetup2 ; Report Error if too Many Pages + JCXZ @SVM_BadModeSetup3 ; Report Error if 0 Pages + + ; Check Validity of X Size + + AND [BP].SVM_XSize, 0FFF8h ; X size Mod 8 Must = 0 + + MOV AX, [BP].SVM_XSize ; Get Logical Screen Width + CMP AX, CS:[SI].M_XSize ; Check against Displayed X + JB @SVM_BadModeSetup4 ; Report Error if too small + CMP AX, CS:[SI].M_XMax ; Check against Max X + JA @SVM_BadModeSetup5 ; Report Error if too big + + ; Check Validity of Y Size + + MOV BX, [BP].SVM_YSize ; Get Logical Screen Height + CMP BX, CS:[SI].M_YSize ; Check against Displayed Y + JB @SVM_BadModeSetup6 ; Report Error if too small + CMP BX, CS:[SI].M_YMax ; Check against Max Y + JA @SVM_BadModeSetup7 ; Report Error if too big + + ; Enough memory to Fit it all? + + SHR AX, 1 ; # of Bytes:Line = XSize/4 + SHR AX, 1 ; # of Bytes:Line = XSize/4 + MUL CX ; AX = Bytes/Line * Pages + MUL BX ; DX:AX = Total VGA mem needed + JNO @SVM_Continue ; Exit if Total Size > 256K + + DEC DX ; Was it Exactly 256K??? + OR DX, AX ; (DX = 1, AX = 0000) + JZ @SVM_Continue ; if so, it's valid... + + jmp @SVM_Continue;0000 + +@SVM_BadModeSetup: + mov ax,8 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup1: + mov ax,1 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup2: + mov ax,2 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup3: + mov ax,3 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup4: + mov ax,4 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup5: + mov ax,5 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup6: + mov ax,6 ; Return Value = False + JMP @SVM_Exit ; Normal Exit +@SVM_BadModeSetup7: + mov ax,7 ; Return Value = False + JMP @SVM_Exit ; Normal Exit + +@SVM_Continue: + + MOV AX, 13H ; Start with Mode 13H + INT 10H ; Let BIOS Set Mode + + OUT_16 SC_INDEX, CHAIN4_OFF ; Disable Chain 4 Mode + OUT_16 SC_INDEX, ASYNC_RESET ; (A)synchronous Reset + OUT_8 MISC_OUTPUT, CS:[SI].M_MiscR ; Set New Timing/Size + OUT_16 SC_INDEX, SEQU_RESTART ; Restart Sequencer ... + + OUT_8 CRTC_INDEX, 11H ; Select Vert Retrace End Register + INC DX ; Point to Data + IN AL, DX ; Get Value, Bit 7 = Protect + AND AL, 7FH ; Mask out Write Protect + OUT DX, AL ; And send it back + + MOV DX, CRTC_INDEX ; Vga Crtc Registers + ADD SI, M_CRTC ; SI -> CRTC Parameter Data + + ; Load Tables of CRTC Parameters from List of Tables + +@SVM_Setup_Table: + + MOV DI, CS:[SI] ; Get Pointer to CRTC Data Tbl + ADD SI, 2 ; Point to next Ptr Entry + OR DI, DI ; A nil Ptr means that we have + JZ @SVM_Set_Data ; finished CRTC programming + +@SVM_Setup_CRTC: + MOV AX, CS:[DI] ; Get CRTC Data from Table + ADD DI, 2 ; Advance Pointer + OR AX, AX ; At End of Data Table? + JZ @SVM_Setup_Table ; If so, Exit & get next Table + + OUT DX, AX ; Reprogram VGA CRTC reg + JMP s @SVM_Setup_CRTC ; Process Next Table Entry + + ; Initialize Page & Scroll info, DI = 0 + +@SVM_Set_Data: + MOV DISPLAY_PAGE, DI ; Display Page = 0 + MOV ACTIVE_PAGE, DI ; Active Page = 0 + MOV CURRENT_PAGE, DI ; Current Page (Offset) = 0 + MOV CURRENT_XOFFSET, DI ; Horz Scroll Index = 0 + MOV CURRENT_YOFFSET, DI ; Vert Scroll Index = 0 + MOV CURRENT_MOFFSET, DI ; Memory Scroll Index = 0 + + MOV AX, VGA_SEGMENT ; Segment for VGA memory + MOV CURRENT_SEGMENT, AX ; Save for Future LES's + + ; Set Logical Screen Width, X Scroll and Our Data + + MOV SI, [BP].SVM_Table ; Get Saved Ptr to Mode Info + MOV AX, [BP].SVM_Xsize ; Get Display Width + + MOV CX, AX ; CX = Logical Width + SUB CX, CS:[SI].M_XSize ; CX = Max X Scroll Value + MOV MAX_XOFFSET, CX ; Set Maximum X Scroll + + SHR AX, 1 ; Bytes = Pixels / 4 + SHR AX, 1 ; Bytes = Pixels / 4 + MOV SCREEN_WIDTH, AX ; Save Width in Pixels + + SHR AX, 1 ; Offset Value = Bytes / 2 + MOV AH, 13h ; CRTC Offset Register Index + XCHG AL, AH ; Switch format for OUT + OUT DX, AX ; Set VGA CRTC Offset Reg + + ; Setup Data table, Y Scroll, Misc for Other Routines + + MOV AX, [BP].SVM_Ysize ; Get Logical Screen Height + + MOV CX, AX ; CX = Logical Height + SUB BX, CS:[SI].M_YSize ; CX = Max Y Scroll Value + MOV MAX_YOFFSET, CX ; Set Maximum Y Scroll + + MOV SCREEN_HEIGHT, AX ; Save Height in Pixels + MUL SCREEN_WIDTH ; AX = Page Size in Bytes, + MOV PAGE_SIZE, AX ; Save Page Size + + MOV CX, [BP].SVM_Pages ; Get # of Pages + MOV LAST_PAGE, CX ; Save # of Pages + + mov bx,0 ; Page # = 0 + MOV DX, BX ; Page 0 Offset = 0 + +@SVM_Set_Pages: + + MOV PAGE_ADDR[BX], DX ; Set Page #(BX) Offset + ADD BX, 2 ; Page#++ + ADD DX, AX ; Compute Addr of Next Page + LOOPx CX, @SVM_Set_Pages ; Loop until all Pages Set + + ; Clear VGA Memory + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; -> Start of VGA memory + + mov ax,0 ; AX = 0 + CLD ; Block Xfer Forwards + MOV CX, 8000H ; 32K * 4 * 2 = 256K + REP STOSW ; Clear dat memory! + + ; Setup Font Pointers + + MOV BH, ROM_8x8_Lo ; Ask for 8x8 Font, 0-127 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_LOW, BP ; Save Char Set Offset + MOV CHARSET_LOW+2, ES ; Save Char Set Segment + + MOV BH, ROM_8x8_Hi ; Ask for 8x8 Font, 128-255 + MOV AX, GET_CHAR_PTR ; Service to Get Pointer + INT 10h ; Call VGA BIOS + + MOV CHARSET_HI, BP ; Save Char Set Offset + MOV CHARSET_HI+2, ES ; Save Char Set Segment + + MOV AX, True ; Return Success Code + +@SVM_EXIT: + ADD SP, 2 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 8 ; Exit & Clean Up Stack + +SET_VGA_MODEX ENDP + + +;================== +;SET_MODEX% (Mode%) +;================== +; +; Quickie Mode Set - Sets Up Mode X to Default Configuration +; +; ENTRY: ModeType = Desired Screen Resolution (0-7) +; (See SET_VGA_MODEX for list) +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +SM_STACK STRUC + DW ?,? ; BP, SI + DD ? ; Caller + SM_Mode DW ? ; Desired Screen Resolution +SM_STACK ENDS + + PUBLIC SET_MODEX + +SET_MODEX PROC FAR + + ;PUSHx BP, SI ; Preserve Important registers + push bp + push si + MOV BP, SP ; Set up Stack Frame + + mov ax,0 ; Assume Failure + MOV BX, [BP].SM_Mode ; Get Desired Mode # + CMP BX, NUM_MODES ; Is it a Valid Mode #? + JAE @SMX_Exit ; If Not, don't Bother + + PUSH BX ; Push Mode Parameter + + SHL BX, 1 ; Scale BX to word Index + MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + + PUSH CS:[SI].M_XSize ; Push Default X Size + PUSH CS:[SI].M_Ysize ; Push Default Y size + MOV AL, CS:[SI].M_Pages ; Get Default # of Pages + mov ah,0 ; Hi Byte = 0 + PUSH AX ; Push # Pages + + CALL f SET_VGA_MODEX ; Set up Mode X! + +@SMX_Exit: + ;POPx SI, BP ; Restore Registers + pop si + pop bp + RET 2 ; Exit & Clean Up Stack + +SET_MODEX ENDP + + + ; ===== BASIC GRAPHICS PRIMITIVES ===== + +;============================ +;CLEAR_VGA_SCREEN (ColorNum%) +;============================ +; +; Clears the active display page +; +; ENTRY: ColorNum = Color Value to fill the page with +; +; EXIT: No meaningful values returned +; + +CVS_STACK STRUC + DW ?,? ; DI, BP + DD ? ; Caller + CVS_COLOR DB ?,? ; Color to Set Screen to +CVS_STACK ENDS + + PUBLIC CLEAR_VGA_SCREEN + +CLEAR_VGA_SCREEN PROC FAR + + ;PUSHx BP, DI ; Preserve Important Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AL, [BP].CVS_COLOR ; Get Color + MOV AH, AL ; Copy for Word Write + CLD ; Block fill Forwards + + MOV CX, PAGE_SIZE ; Get Size of Page + SHR CX, 1 ; Divide by 2 for Words + REP STOSW ; Block Fill VGA memory + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 2 ; Exit & Clean Up Stack + +CLEAR_VGA_SCREEN ENDP + + +;=================================== +;SET_POINT (Xpos%, Ypos%, ColorNum%) +;=================================== +; +; Plots a single Pixel on the active display page +; +; ENTRY: Xpos = X position to plot pixel at +; Ypos = Y position to plot pixel at +; ColorNum = Color to plot pixel with +; +; EXIT: No meaningful values returned +; + +SP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + SETP_Color DB ?,? ; Color of Point to Plot + SETP_Ypos DW ? ; Y pos of Point to Plot + SETP_Xpos DW ? ; X pos of Point to Plot +SP_STACK ENDS + + PUBLIC SET_POINT + +SET_POINT PROC FAR + + ;PUSHx BP, DI ; Preserve Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].SETP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].SETP_Xpos ; Get Xpos + MOV CX, BX ; Copy to extract Plane # from + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AX, MAP_MASK_PLANE1 ; Map Mask & Plane Select Register + AND CL, PLANE_BITS ; Get Plane Bits + SHL AH, CL ; Get Plane Select Value + OUT_16 SC_Index, AX ; Select Plane + + MOV AL,[BP].SETP_Color ; Get Pixel Color + MOV ES:[DI+BX], AL ; Draw Pixel + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 6 ; Exit and Clean up Stack + +SET_POINT ENDP + + +;========================== +;READ_POINT% (Xpos%, Ypos%) +;========================== +; +; Read the color of a pixel from the Active Display Page +; +; ENTRY: Xpos = X position of pixel to read +; Ypos = Y position of pixel to read +; +; EXIT: AX = Color of Pixel at (Xpos, Ypos) +; + +RP_STACK STRUC + DW ?,? ; BP, DI + DD ? ; Caller + RP_Ypos DW ? ; Y pos of Point to Read + RP_Xpos DW ? ; X pos of Point to Read +RP_STACK ENDS + + PUBLIC READ_POINT + +READ_POINT PROC FAR + + ;PUSHx BP, DI ; Preserve Registers + push bp + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].RP_Ypos ; Get Line # of Pixel + MUL SCREEN_WIDTH ; Get Offset to Start of Line + + MOV BX, [BP].RP_Xpos ; Get Xpos + MOV CX, BX + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + SHR BX, 1 ; X offset (Bytes) = Xpos/4 + ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + MOV AL, READ_MAP ; GC Read Mask Register + MOV AH, CL ; Get Xpos + AND AH, PLANE_BITS ; & mask out Plane # + OUT_16 GC_INDEX, AX ; Select Plane to read in + + mov ah,0 ; Clear Return Value Hi byte + MOV AL, ES:[DI+BX] ; Get Color of Pixel + + ;POPx DI, BP ; Restore Saved Registers + pop di + pop bp + RET 4 ; Exit and Clean up Stack + +READ_POINT ENDP + + +;====================================================== +;FILL_BLOCK (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;====================================================== +; +; Fills a rectangular block on the active display Page +; +; ENTRY: Xpos1 = Left X position of area to fill +; Ypos1 = Top Y position of area to fill +; Xpos2 = Right X position of area to fill +; Ypos2 = Bottom Y position of area to fill +; ColorNum = Color to fill area with +; +; EXIT: No meaningful values returned +; + +FB_STACK STRUC + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + FB_Color DB ?,? ; Fill Color + FB_Ypos2 DW ? ; Y pos of Lower Right Pixel + FB_Xpos2 DW ? ; X pos of Lower Right Pixel + FB_Ypos1 DW ? ; Y pos of Upper Left Pixel + FB_Xpos1 DW ? ; X pos of Upper Left Pixel +FB_STACK ENDS + + PUBLIC FILL_BLOCK + +FILL_BLOCK PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + + ; Validate Pixel Coordinates + ; If necessary, Swap so X1 <= X2, Y1 <= Y2 + + MOV AX, [BP].FB_Ypos1 ; AX = Y1 is Y1< Y2? + MOV BX, [BP].FB_Ypos2 ; BX = Y2 + CMP AX, BX + JLE @FB_NOSWAP1 + + MOV [BP].FB_Ypos1, BX ; Swap Y1 and Y2 and save Y1 + XCHG AX, BX ; on stack for future use + +@FB_NOSWAP1: + SUB BX, AX ; Get Y width + INC BX ; Add 1 to avoid 0 value + MOV [BP].FB_Ypos2, BX ; Save in Ypos2 + + MUL SCREEN_WIDTH ; Mul Y1 by Bytes per Line + ADD DI, AX ; DI = Start of Line Y1 + + MOV AX, [BP].FB_Xpos1 ; Check X1 <= X2 + MOV BX, [BP].FB_Xpos2 ; + CMP AX, BX + JLE @FB_NOSWAP2 ; Skip Ahead if Ok + + MOV [BP].FB_Xpos2, AX ; Swap X1 AND X2 and save X2 + XCHG AX, BX ; on stack for future use + + ; All our Input Values are in order, Now determine + ; How many full "bands" 4 pixels wide (aligned) there + ; are, and if there are partial bands (<4 pixels) on + ; the left and right edges. + +@FB_NOSWAP2: + MOV DX, AX ; DX = X1 (Pixel Position) + SHR DX, 1 ; DX/4 = Bytes into Line + SHR DX, 1 ; DX/4 = Bytes into Line + ADD DI, DX ; DI = Addr of Upper-Left Corner + + MOV CX, BX ; CX = X2 (Pixel Position) + SHR CX, 1 ; CX/4 = Bytes into Line + SHR CX, 1 ; CX/4 = Bytes into Line + + CMP DX, CX ; Start and end in same band? + JNE @FB_NORMAL ; if not, check for l & r edges + JMP @FB_ONE_BAND_ONLY ; if so, then special processing + +@FB_NORMAL: + SUB CX, DX ; CX = # bands -1 + MOV SI, AX ; SI = PLANE#(X1) + AND SI, PLANE_BITS ; if Left edge is aligned then + JZ @FB_L_PLANE_FLUSH ; no special processing.. + + ; Draw "Left Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Left_Clip_Mask[SI] ; Set Left Edge Plane Mask + + MOV SI, DI ; SI = Copy of Start Addr (UL) + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_LEFT_LOOP: + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_LEFT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Left Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_LEFT_LOOP ; loop until left strip is drawn + +@FB_LEFT_CONT: + + INC DI ; Point to Middle (or Right) Block + DEC CX ; Reset CX instead of JMP @FB_RIGHT + +@FB_L_PLANE_FLUSH: + INC CX ; Add in Left band to middle block + + ; DI = Addr of 1st middle Pixel (band) to fill + ; CX = # of Bands to fill -1 + +@FB_RIGHT: + MOV SI, [BP].FB_Xpos2 ; Get Xpos2 + AND SI, PLANE_BITS ; Get Plane values + CMP SI, 0003 ; Plane = 3? + JE @FB_R_EDGE_FLUSH ; Hey, add to middle + + ; Draw "Right Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Right_Clip_Mask[SI] ; Right Edge Plane Mask + + MOV SI, DI ; Get Addr of Left Edge + ADD SI, CX ; Add Width-1 (Bands) + DEC SI ; To point to top of Right Edge + + MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_RIGHT_LOOP: + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_RIGHT_CONT ; Exit loop if all Lines Drawn + + MOV ES:[SI], AL ; Fill in Right Edge Pixels + ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_RIGHT_LOOP ; loop until left strip is drawn + +@FB_RIGHT_CONT: + + DEC CX ; Minus 1 for Middle bands + JZ @FB_EXIT ; Uh.. no Middle bands... + +@FB_R_EDGE_FLUSH: + + ; DI = Addr of Upper Left block to fill + ; CX = # of Bands to fill in (width) + + OUT_8 SC_Data, ALL_PLANES ; Write to All Planes + + MOV DX, SCREEN_WIDTH ; DX = DI Increment + SUB DX, CX ; = Screen_Width-# Planes Filled + + MOV BX, CX ; BX = Quick Refill for CX + MOV SI, [BP].FB_Ypos2 ; SI = # of Line to Fill + MOV AL, [BP].FB_Color ; Get Fill Color + +@FB_MIDDLE_LOOP: + REP STOSB ; Fill in entire line + + MOV CX, BX ; Recharge CX (Line Width) + ADD DI, DX ; Point to start of Next Line + LOOPx SI, @FB_MIDDLE_LOOP ; Loop until all lines drawn + + JMP s @FB_EXIT ; Outa here + +@FB_ONE_BAND_ONLY: + MOV SI, AX ; Get Left Clip Mask, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV SI, BX ; Get Right Clip Mask, Save X2 + AND SI, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[SI] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].FB_Ypos2 ; Get # of Lines to draw + MOV AL, [BP].FB_Color ; Get Fill Color + MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + +@FB_ONE_LOOP: + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPjz CX, @FB_EXIT ; Exit loop if all Lines Drawn + + MOV ES:[DI], AL ; Fill in Pixels + ADD DI, BX ; Point to Next Line (Below) + LOOPx CX, @FB_ONE_LOOP ; loop until left strip is drawn + +@FB_EXIT: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 10 ; Exit and Clean up Stack + +FILL_BLOCK ENDP + + +;===================================================== +;DRAW_LINE (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) +;===================================================== +; +; Draws a Line on the active display page +; +; ENTRY: Xpos1 = X position of first point on line +; Ypos1 = Y position of first point on line +; Xpos2 = X position of last point on line +; Ypos2 = Y position of last point on line +; ColorNum = Color to draw line with +; +; EXIT: No meaningful values returned +; + +DL_STACK STRUC + DW ?x1 ; DI, SI, BP + DW ?x1 ; DI, SI, BP + DW ?x1 ; DI, SI, BP + DD ? ; Caller + DL_ColorF DB ?,? ; Line Draw Color + DL_Ypos2 DW ? ; Y pos of last point + DL_Xpos2 DW ? ; X pos of last point + DL_Ypos1 DW ? ; Y pos of first point + DL_Xpos1 DW ? ; X pos of first point +DL_STACK ENDS + + PUBLIC DRAW_LINE + +DRAW_LINE PROC FAR + + ;PUSHx BP, SI, DI ; Preserve Important Registers + push bp + push si + push di + MOV BP, SP ; Set up Stack Frame + CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + MOV CH, [BP].DL_ColorF ; Save Line Color in CH + + ; Check Line Type + + MOV SI, [BP].DL_Xpos1 ; AX = X1 is X1< X2? + MOV DI, [BP].DL_Xpos2 ; DX = X2 + CMP SI, DI ; Is X1 < X2 + JE @DL_VLINE ; If X1=X2, Draw Vertical Line + JL @DL_NOSWAP1 ; If X1 < X2, don't swap + + XCHG SI, DI ; X2 IS > X1, SO SWAP THEM + +@DL_NOSWAP1: + + ; SI = X1, DI = X2 + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 is Y1 <> Y2? + CMP AX, [BP].DL_Ypos2 ; Y1 = Y2? + JE @DL_HORZ ; If so, Draw a Horizontal Line + + JMP @DL_BREZHAM ; Diagonal line... go do it... + + ; This Code draws a Horizontal Line in Mode X where: + ; SI = X1, DI = X2, and AX = Y1/Y2 + +@DL_HORZ: + + MUL SCREEN_WIDTH ; Offset = Ypos * Screen_Width + MOV DX, AX ; CX = Line offset into Page + + MOV AX, SI ; Get Left edge, Save X1 + AND SI, PLANE_BITS ; Mask out Row # + MOV BL, Left_Clip_Mask[SI] ; Get Left Edge Mask + MOV CX, DI ; Get Right edge, Save X2 + AND DI, PLANE_BITS ; Mask out Row # + MOV BH, Right_Clip_Mask[DI] ; Get Right Edge Mask byte + + SHR AX, 1 ; Get X1 Byte # (=X1/4) + SHR CX, 1 ; Get X2 Byte # (=X2/4) + SHR AX, 1 ; Get X1 Byte # (=X1/4) + SHR CX, 1 ; Get X2 Byte # (=X2/4) + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, DX ; Point to Start of Line + ADD DI, AX ; Point to Pixel X1 + + SUB CX, AX ; CX = # Of Bands (-1) to set + JNZ @DL_LONGLN ; jump if longer than one segment + + AND BL, BH ; otherwise, merge clip masks + +@DL_LONGLN: + + OUT_8 SC_Data, BL ; Set the Left Clip Mask + + MOV AL, [BP].DL_ColorF ; Get Line Color + MOV BL, AL ; BL = Copy of Line Color + STOSB ; Set Left (1-4) Pixels + + JCXZ @DL_EXIT ; Done if only one Line Segment + + DEC CX ; CX = # of Middle Segments + JZ @DL_XRSEG ; If no middle segments.... + + ; Draw Middle Segments + + OUT_8 DX, ALL_PLANES ; Write to ALL Planes + + MOV AL, BL ; Get Color from BL + REP STOSB ; Draw Middle (4 Pixel) Segments + +@DL_XRSEG: + OUT_8 DX, BH ; Select Planes for Right Clip Mask + MOV AL, BL ; Get Color Value + STOSB ; Draw Right (1-4) Pixels + + JMP s @DL_EXIT ; We Are Done... + + + ; This Code Draws A Vertical Line. On entry: + ; CH = Line Color, SI & DI = X1 + +@DL_VLINE: + + MOV AX, [BP].DL_Ypos1 ; AX = Y1 + MOV SI, [BP].DL_Ypos2 ; SI = Y2 + CMP AX, SI ; Is Y1 < Y2? + JLE @DL_NOSWAP2 ; if so, Don't Swap them + + XCHG AX, SI ; Ok, NOW Y1 < Y2 + +@DL_NOSWAP2: + + SUB SI, AX ; SI = Line Height (Y2-Y1+1) + INC SI + + ; AX = Y1, DI = X1, Get offset into Page into AX + + MUL SCREEN_WIDTH ; Offset = Y1 (AX) * Screen Width + MOV DX, DI ; Copy Xpos into DX + SHR DI, 1 ; DI = Xpos/4 + SHR DI, 1 ; DI = Xpos/4 + ADD AX, DI ; DI = Xpos/4 + ScreenWidth * Y1 + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + ADD DI, AX ; Point to Pixel X1, Y1 + + ;Select Plane + + MOV CL, DL ; CL = Save X1 + AND CL, PLANE_BITS ; Get X1 MOD 4 (Plane #) + MOV AX, MAP_MASK_PLANE1 ; Code to set Plane #1 + SHL AH, CL ; Change to Correct Plane # + OUT_16 SC_Index, AX ; Select Plane + + MOV AL, CH ; Get Saved Color + MOV BX, SCREEN_WIDTH ; Get Offset to Advance Line By + +@DL_VLoop: + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPjz SI, @DL_EXIT ; Lines--, Exit if done + + MOV ES:[DI], AL ; Draw Single Pixel + ADD DI, BX ; Point to Next Line + LOOPx SI, @DL_VLoop ; Lines--, Loop until Done + +@DL_EXIT: + + JMP @DL_EXIT2 ; Done! + + ; This code Draws a diagonal line in Mode X + +@DL_BREZHAM: + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, [BP].DL_Ypos1 ; get Y1 value + MOV BX, [BP].DL_Ypos2 ; get Y2 value + MOV CX, [BP].DL_Xpos1 ; Get Starting Xpos + + CMP BX, AX ; Y2-Y1 is? + JNC @DL_DeltaYOK ; if Y2>=Y1 then goto... + + XCHG BX, AX ; Swap em... + MOV CX, [BP].DL_Xpos2 ; Get New Starting Xpos + +@DL_DeltaYOK: + MUL SCREEN_WIDTH ; Offset = SCREEN_WIDTH * Y1 + + ADD DI, AX ; DI -> Start of Line Y1 on Page + MOV AX, CX ; AX = Xpos (X1) + SHR AX, 1 ; /4 = Byte Offset into Line + SHR AX, 1 ; /4 = Byte Offset into Line + ADD DI, AX ; DI = Starting pos (X1,Y1) + + MOV AL, 11h ; Staring Mask + AND CL, PLANE_BITS ; Get Plane # + SHL AL, CL ; and shift into place + MOV AH, [BP].DL_ColorF ; Color in Hi Bytes + + PUSH AX ; Save Mask,Color... + + MOV AH, AL ; Plane # in AH + MOV AL, MAP_MASK ; Select Plane Register + OUT_16 SC_Index, AX ; Select initial plane + + MOV AX, [BP].DL_Xpos1 ; get X1 value + MOV BX, [BP].DL_Ypos1 ; get Y1 value + MOV CX, [BP].DL_Xpos2 ; get X2 value + MOV DX, [BP].DL_Ypos2 ; get Y2 value + + MOV BP, SCREEN_WIDTH ; Use BP for Line width to + ; to avoid extra memory access + + SUB DX, BX ; figure Delta_Y + JNC @DL_DeltaYOK2 ; jump if Y2 >= Y1 + + ADD BX, DX ; put Y2 into Y1 + NEG DX ; abs(Delta_Y) + XCHG AX, CX ; and exchange X1 and X2 + +@DL_DeltaYOK2: + MOV BX, 08000H ; seed for fraction accumulator + + SUB CX, AX ; figure Delta_X + JC @DL_DrawLeft ; if negative, go left + + JMP @DL_DrawRight ; Draw Line that slopes right + +@DL_DrawLeft: + + NEG CX ; abs(Delta_X) + + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepLeft ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the left in Mode X + +@DL_ShallowLeft: + mov ax,0 ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Left, and Maybe Down... + +@DL_SLLLoop: + MOV ES:[DI], AH ; set first pixel, plane data set up + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLLL2nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL2nc: + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + + ADD SI, BX ; add numerator to accumulator, + JNC @DL_SLLL3nc ; move down on carry + + ADD DI, BP ; Move Down one line... + +@DL_SLLL3nc: ; Now move left a pixel... + DEC DI ; Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLLLoop ; loop until done + +@DL_SLLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a steep line to the left in Mode X + +@DL_SteepLeft: + mov ax,0 ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe left + +@DL_STLLoop: + + MOV ES:[DI], AH ; set first pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc2 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + + ADD SI, BX ; add numerator to accumulator + JNC @DL_STLnc3 ; No carry, just move down! + + DEC DI ; Move Left one addr + ROR AL, 1 ; Move Left one plane, back on 0 1 2 + CMP AL, 87h ; Wrap?, if AL <88 then Carry set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@DL_STLnc3: + ADD DI, BP ; advance to next line. + JMP s @DL_STLLoop ; Loop until done + +@DL_STLExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a line that goes to the Right... + +@DL_DrawRight: + CMP CX, DX ; is Delta_X < Delta_Y? + JB @DL_SteepRight ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the Right in Mode X + +@DL_ShallowRight: + mov ax,0 ; zero low word of Delta_Y * 10000h + SUB AX, DX ; DX:AX <- DX * 0FFFFh + SBB DX, 0 ; include carry + DIV CX ; divide by Delta_X + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Right, and Maybe Down... + +@DL_SLRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR2nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR2nc: ; Now move right a pixel... + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + + ADD SI, BX ; add numerator to accumulator + JNC @DL_SLR3nc ; don't move down if carry not set + + ADD DI, BP ; Move Down one line... + +@DL_SLR3nc: + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + JMP s @DL_SLRLoop ; loop till done + +@DL_SLRExit: + JMP @DL_EXIT2 ; and exit + + ; Draw a Steep line to the Right in Mode X + +@DL_SteepRight: + mov ax,0 ; zero low word of Delta_Y * 10000h + XCHG DX, CX ; Delta_Y switched with Delta_X + DIV CX ; divide by Delta_Y + + MOV SI, BX ; SI = Accumulator + MOV BX, AX ; BX = Add Fraction + POP AX ; Get Color, Bit mask + MOV DX, SC_Data ; Sequence controller data register + INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe Right + +@STRLoop: + MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc2 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc2: + ADD DI, BP ; advance to next line. + + MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + + ADD SI, BX ; add numerator to accumulator + JNC @STRnc3 ; if no carry then just go down... + + ROL AL, 1 ; Move Right one addr if Plane = 0 + CMP AL, 12h ; Wrap? if AL >12 then Carry not set + ADC DI, 0 ; Adjust Address: DI = DI + Carry + OUT DX, AL ; Set up New Bit Plane mask + +@STRnc3: + ADD DI, BP ; advance to next line. + JMP s @STRLoop ; loop till done + +@DL_EXIT2: + ;POPx DI, SI, BP ; Restore Saved Registers + pop di + pop si + pop bp + RET 10 ; Exit and Clean up Stack + +DRAW_LINE ENDP + + + ; ===== DAC COLOR REGISTER ROUTINES ===== + +;================================================= +;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%) +;================================================= +; +; Sets a single (RGB) Vga Palette Register +; +; ENTRY: Register = The DAC # to modify (0-255) +; Red = The new Red Intensity (0-63) +; Green = The new Green Intensity (0-63) +; Blue = The new Blue Intensity (0-63) +; +; EXIT: No meaningful values returned +; + +SDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDR_Blue DB ?,? ; Blue Data Value + SDR_Green DB ?,? ; Green Data Value + SDR_Red DB ?,? ; Red Data Value + SDR_Register DB ?,? ; Palette Register # +SDR_STACK ENDS + + PUBLIC SET_DAC_REGISTER + +SET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to modify + + OUT_8 DAC_WRITE_ADDR, [BP].SDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + OUT_8 DX, [BP].SDR_Red ; Set Red Intensity + OUT_8 DX, [BP].SDR_Green ; Set Green Intensity + OUT_8 DX, [BP].SDR_Blue ; Set Blue Intensity + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +SET_DAC_REGISTER ENDP + +;==================================================== +;GET_DAC_REGISTER (Register%, &Red%, &Green%, &Blue%) +;==================================================== +; +; Reads the RGB Values of a single Vga Palette Register +; +; ENTRY: Register = The DAC # to read (0-255) +; Red = Offset to Red Variable in DS +; Green = Offset to Green Variable in DS +; Blue = Offset to Blue Variable in DS +; +; EXIT: The values of the integer variables Red, +; Green, and Blue are set to the values +; taken from the specified DAC register. +; + +GDR_STACK STRUC + DW ? ; BP + DD ? ; Caller + GDR_Blue DW ? ; Addr of Blue Data Value in DS + GDR_Green DW ? ; Addr of Green Data Value in DS + GDR_Red DW ? ; Addr of Red Data Value in DS + GDR_Register DB ?,? ; Palette Register # +GDR_STACK ENDS + + PUBLIC GET_DAC_REGISTER + +GET_DAC_REGISTER PROC FAR + + PUSH BP ; Save BP + MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to read in + + OUT_8 DAC_READ_ADDR, [BP].GDR_Register + + MOV DX, PEL_DATA_REG ; Dac Data Register + mov ax,0 ; Clear AX + + IN AL, DX ; Read Red Value + MOV BX, [BP].GDR_Red ; Get Address of Red% + MOV [BX], AX ; *Red% = AX + + IN AL, DX ; Read Green Value + MOV BX, [BP].GDR_Green ; Get Address of Green% + MOV [BX], AX ; *Green% = AX + + IN AL, DX ; Read Blue Value + MOV BX, [BP].GDR_Blue ; Get Address of Blue% + MOV [BX], AX ; *Blue% = AX + + POP BP ; Restore Registers + RET 8 ; Exit & Clean Up Stack + +GET_DAC_REGISTER ENDP + + +;=========================================================== +;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%) +;=========================================================== +; +; Sets a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to Block of palette data +; StartReg = First Register # in range to set (0-255) +; EndReg = Last Register # in Range to set (0-255) +; Sync = Wait for Vertical Retrace Flag (Boolean) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +LDR_STACK STRUC + DW ?x1 ; BP, DS, SI + DW ?x1 ; BP, DS, SI + DW ?x1 ; BP, DS, SI + DD ? ; Caller + LDR_Sync DW ? ; Vertical Sync Flag + LDR_EndReg DB ?,? ; Last Register # + LDR_StartReg DB ?,? ; First Register # + LDR_PalData DD ? ; Far Ptr to Palette Data +LDR_STACK ENDS + + PUBLIC LOAD_DAC_REGISTERS + +LOAD_DAC_REGISTERS PROC FAR + + ;PUSHx BP, DS, SI ; Save Registers + push bp + push ds + push si + mov BP, SP ; Set up Stack Frame + + mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag + or AX, AX ; is Sync Flag = 0? + jz @LDR_Load ; if so, skip call + + call f SYNC_DISPLAY ; wait for vsync + + ; Determine register #'s, size to copy, etc + +@LDR_Load: + + lds SI, [BP].LDR_PalData ; DS:SI -> Palette Data + mov DX, DAC_WRITE_ADDR ; DAC register # selector + + mov ax,0, BX ; Clear for byte loads + mov AL, [BP].LDR_StartReg ; Get Start Register + mov BL, [BP].LDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block OUTs forward + out DX, AL ; set up correct register # + + ; Load a block of DAC Registers + + mov DX, PEL_DATA_REG ; Dac Data Register + + ;rep outsb ; block set DAC registers + + ;POPx SI, DS, BP ; Restore Registers + pop si + pop ds + pop bp + ret 10 ; Exit & Clean Up Stack + +LOAD_DAC_REGISTERS ENDP + + +;==================================================== +;READ_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%) +;==================================================== +; +; Reads a Block of Vga Palette Registers +; +; ENTRY: PalData = Far Pointer to block to store palette data +; StartReg = First Register # in range to read (0-255) +; EndReg = Last Register # in Range to read (0-255) +; +; EXIT: No meaningful values returned +; +; NOTES: PalData is a linear array of 3 byte Palette values +; in the order: Red (0-63), Green (0-63), Blue (0-63) +; + +RDR_STACK STRUC + DW ?x1 ; BP, ES, DI + DW ?x1 ; BP, ES, DI + DW ?x1 ; BP, ES, DI + DD ? ; Caller + RDR_EndReg DB ?,? ; Last Register # + RDR_StartReg DB ?,? ; First Register # + RDR_PalData DD ? ; Far Ptr to Palette Data +RDR_STACK ENDS + + PUBLIC READ_DAC_REGISTERS + +READ_DAC_REGISTERS PROC FAR + + ;PUSHx BP, ES, DI ; Save Registers + push bp + push es + push di + mov BP, SP ; Set up Stack Frame + + ; Determine register #'s, size to copy, etc + + les DI, [BP].RDR_PalData ; ES:DI -> Palette Buffer + mov DX, DAC_READ_ADDR ; DAC register # selector + + mov ax,0, BX ; Clear for byte loads + mov AL, [BP].RDR_StartReg ; Get Start Register + mov BL, [BP].RDR_EndReg ; Get End Register + + sub BX, AX ; BX = # of DAC registers -1 + inc BX ; BX = # of DAC registers + mov CX, BX ; CX = # of DAC registers + add CX, BX ; CX = " " * 2 + add CX, BX ; CX = " " * 3 + cld ; Block INs forward + + ; Read a block of DAC Registers + + out DX, AL ; set up correct register # + mov DX, PEL_DATA_REG ; Dac Data Register + + ;rep insb ; block read DAC registers + + ;POPx DI, ES, BP ; Restore Registers + pop di + pop es + pop bp + ret 8 ; Exit & Clean Up Stack + +READ_DAC_REGISTERS ENDP + + + ; ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +;========================= +;SET_ACTIVE_PAGE (PageNo%) +;========================= +; +; Sets the active display Page to be used for future drawing +; +; ENTRY: PageNo = Display Page to make active +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SAP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SAP_Page DW ? ; Page # for Drawing +SAP_STACK ENDS + + PUBLIC SET_ACTIVE_PAGE + +SET_ACTIVE_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SAP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SAP_Exit ; IF Not, Do Nothing + + MOV ACTIVE_PAGE, BX ; Set Active Page # + + SHL BX, 1 ; Scale Page # to Word + MOV AX, PAGE_ADDR[BX] ; Get offset to Page + + MOV CURRENT_PAGE, AX ; And set for future LES's + +@SAP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_ACTIVE_PAGE ENDP + + +;================ +;GET_ACTIVE_PAGE% +;================ +; +; Returns the Video Page # currently used for Drawing +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page used for Drawing +; + + PUBLIC GET_ACTIVE_PAGE + +GET_ACTIVE_PAGE PROC FAR + + MOV AX, ACTIVE_PAGE ; Get Active Page # + RET ; Exit and Clean up Stack + +GET_ACTIVE_PAGE ENDP + + +;=============================== +;SET_DISPLAY_PAGE (DisplayPage%) +;=============================== +; +; Sets the currently visible display page. +; When called this routine syncronizes the display +; to the vertical blank. +; +; ENTRY: PageNo = Display Page to show on the screen +; (values: 0 to Number of Pages - 1) +; +; EXIT: No meaningful values returned +; + +SDP_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDP_Page DW ? ; Page # to Display... +SDP_STACK ENDS + + PUBLIC SET_DISPLAY_PAGE + +SET_DISPLAY_PAGE PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + MOV BX, [BP].SDP_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SDP_Exit ; IF Not, Do Nothing + + MOV DISPLAY_PAGE, BX ; Set Display Page # + + SHL BX, 1 ; Scale Page # to Word + MOV CX, PAGE_ADDR[BX] ; Get offset in memory to Page + ADD CX, CURRENT_MOFFSET ; Adjust for any scrolling + + ; Wait if we are currently in a Vertical Retrace + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @DP_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new page + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, CL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, CH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@DP_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @DP_WAIT1 ; If Not, wait for it + + ; Now Set Display Starting Address + + +@SDP_Exit: + POP BP ; Restore Registers + RET 2 ; Exit and Clean up Stack + +SET_DISPLAY_PAGE ENDP + + +;================= +;GET_DISPLAY_PAGE% +;================= +; +; Returns the Video Page # currently displayed +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Video Page being displayed +; + + PUBLIC GET_DISPLAY_PAGE + +GET_DISPLAY_PAGE PROC FAR + + MOV AX, DISPLAY_PAGE ; Get Display Page # + RET ; Exit & Clean Up Stack + +GET_DISPLAY_PAGE ENDP + + +;======================================= +;SET_WINDOW (DisplayPage%, Xpos%, Ypos%) +;======================================= +; +; Since a Logical Screen can be larger than the Physical +; Screen, Scrolling is possible. This routine sets the +; Upper Left Corner of the Screen to the specified Pixel. +; Also Sets the Display page to simplify combined page +; flipping and scrolling. When called this routine +; syncronizes the display to the vertical blank. +; +; ENTRY: DisplayPage = Display Page to show on the screen +; Xpos = # of pixels to shift screen right +; Ypos = # of lines to shift screen down +; +; EXIT: No meaningful values returned +; + +SW_STACK STRUC + DW ? ; BP + DD ? ; Caller + SW_Ypos DW ? ; Y pos of UL Screen Corner + SW_Xpos DW ? ; X pos of UL Screen Corner + SW_Page DW ? ; (new) Display Page +SW_STACK ENDS + + PUBLIC SET_WINDOW + +SET_WINDOW PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + ; Check if our Scroll Offsets are Valid + + MOV BX, [BP].SW_Page ; Get Desired Page # + CMP BX, LAST_PAGE ; Is Page # Valid? + JAE @SW_Exit ; IF Not, Do Nothing + + MOV AX, [BP].SW_Ypos ; Get Desired Y Offset + CMP AX, MAX_YOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + MOV CX, [BP].SW_Xpos ; Get Desired X Offset + CMP CX, MAX_XOFFSET ; Is it Within Limits? + JA @SW_Exit ; if not, exit + + ; Compute proper Display start address to use + + MUL SCREEN_WIDTH ; AX = YOffset * Line Width + SHR CX, 1 ; CX / 4 = Bytes into Line + SHR CX, 1 ; CX / 4 = Bytes into Line + ADD AX, CX ; AX = Offset of Upper Left Pixel + + MOV CURRENT_MOFFSET, AX ; Save Offset Info + + MOV DISPLAY_PAGE, BX ; Set Current Page # + SHL BX, 1 ; Scale Page # to Word + ADD AX, PAGE_ADDR[BX] ; Get offset in VGA to Page + MOV BX, AX ; BX = Desired Display Start + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait if we are currently in a Vertical Retrace + +@SW_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SW_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new window + + MOV DX, CRTC_Index ; We Change the VGA Sequencer + MOV AL, START_DISP_LO ; Display Start Low Register + MOV AH, BL ; Low 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr Low + + MOV AL, START_DISP_HI ; Display Start High Register + MOV AH, BH ; High 8 Bits of Start Addr + OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + MOV DX, INPUT_1 ; Input Status #1 Register + +@SW_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SW_WAIT1 ; If Not, wait for it + + ; Now Set the Horizontal Pixel Pan values + + OUT_8 ATTRIB_Ctrl, PIXEL_PAN_REG ; Select Pixel Pan Register + + MOV AX, [BP].SW_Xpos ; Get Desired X Offset + AND AL, 03 ; Get # of Pixels to Pan (0-3) + SHL AL, 1 ; Shift for 256 Color Mode + OUT DX, AL ; Fine tune the display! + +@SW_Exit: + POP BP ; Restore Saved Registers + RET 6 ; Exit and Clean up Stack + +SET_WINDOW ENDP + + +;============= +;GET_X_OFFSET% +;============= +; +; Returns the X coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Horizontal Scroll Offset +; + + PUBLIC GET_X_OFFSET + +GET_X_OFFSET PROC FAR + + MOV AX, CURRENT_XOFFSET ; Get current horz offset + RET ; Exit & Clean Up Stack + +GET_X_OFFSET ENDP + + +;============= +;GET_Y_OFFSET% +;============= +; +; Returns the Y coordinate of the Pixel currently display +; in the upper left corner of the display +; +; ENTRY: No Parameters are passed +; +; EXIT: AX = Current Vertical Scroll Offset +; + + PUBLIC GET_Y_OFFSET + +GET_Y_OFFSET PROC FAR + + MOV AX, CURRENT_YOFFSET ; Get current vertical offset + RET ; Exit & Clean Up Stack + +GET_Y_OFFSET ENDP + + +;============ +;SYNC_DISPLAY +;============ +; +; Pauses the computer until the next Vertical Retrace starts +; +; ENTRY: No Parameters are passed +; +; EXIT: No meaningful values returned +; + + PUBLIC SYNC_DISPLAY + +SYNC_DISPLAY PROC FAR + + MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait for any current retrace to end + +@SD_WAIT0: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; In Display mode yet? + JNZ @SD_WAIT0 ; If Not, wait for it + + ; Wait for the start of the next vertical retrace + +@SD_WAIT1: + IN AL, DX ; Get VGA status + AND AL, VERT_RETRACE ; Vertical Retrace Start? + JZ @SD_WAIT1 ; If Not, wait for it + + RET ; Exit & Clean Up Stack + +SYNC_DISPLAY ENDP + + + ; ===== TEXT DISPLAY ROUTINES ===== + +;================================================== +;GPRINTC (CharNum%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================== +; +; Draws an ASCII Text Character using the currently selected +; 8x8 font on the active display page. It would be a simple +; exercise to make this routine process variable height fonts. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +GPC_STACK STRUC + GPC_Width DW ? ; Screen Width-1 + GPC_Lines DB ?,? ; Scan lines to Decode + GPC_T_SETS DW ? ; Saved Charset Segment + GPC_T_SETO DW ? ; Saved Charset Offset + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + GPC_ColorB DB ?,? ; Background Color + GPC_ColorF DB ?,? ; Text Color + GPC_Ypos DW ? ; Y Position to Print at + GPC_Xpos DW ? ; X position to Print at + GPC_Char DB ?,? ; Character to Print +GPC_STACK ENDS + + PUBLIC GPRINTC + +GPRINTC PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].GPC_Width, BX ; Save for later use + + MUL [BP].GPC_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].GPC_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 1 ; Bytes into Line = Xpos/4 + SHR AX, 1 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].GPC_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @GPC_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @GPC_Set_Char ; Go Setup Character Ptr + +@GPC_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@GPC_Set_Char: + MOV [BP].GPC_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].GPC_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].GPC_Lines, AL ; Save on Stack + + MOV DS, [BP].GPC_T_SETS ; Point to character set + +@GPC_DECODE_CHAR_BYTE: + + MOV SI, [BP].GPC_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].GPC_T_SETO, SI ; And save new Pointer... + + mov ax,0 ; Clear AX + + ;mov bl,0 ; Clear BL + mov bl,0 + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_LEFT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_LEFT1BITS: + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_LEFT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@GPC_NO_LEFT0BITS: + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_MIDDLE1BITS ; Skip if no pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE1BITS: + XOR AL, ALL_PLANES ; Invert mask for Background + JZ @GPC_NO_MIDDLE0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_MIDDLE0BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @GPC_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @GPC_NO_RIGHT1BITS ; Skip if No Pixels to set + + MOV AH, [BP].GPC_ColorF ; Get Foreground Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT1BITS: + + XOR AL, CH ; Invert mask for Background + JZ @GPC_NO_RIGHT0BITS ; Hey, no need for this + + MOV AH, [BP].GPC_ColorB ; Get background Color + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@GPC_NO_RIGHT0BITS: + DEC DI ; Adjust for Next Line Advance + +@GPC_NEXT_LINE: + ADD DI, [BP].GPC_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].GPC_Lines ; Count Down Lines + JZ @GPC_EXIT ; Ok... Done! + + JMP @GPC_DECODE_CHAR_BYTE ; Again! Hey! + +@GPC_EXIT: + ADD SP, 08 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 10 ; Exit and Clean up Stack + +GPRINTC ENDP + + +;========================================== +;TGPRINTC (CharNum%, Xpos%, Ypos%, ColorF%) +;========================================== +; +; Transparently draws an ASCII Text Character using the +; currently selected 8x8 font on the active display page. +; +; ENTRY: CharNum = ASCII character # to draw +; Xpos = X position to draw Character at +; Ypos = Y position of to draw Character at +; ColorF = Color to draw text character in +; +; EXIT: No meaningful values returned +; + +TGP_STACK STRUC + TGP_Width DW ? ; Screen Width-1 + TGP_Lines DB ?,? ; Scan lines to Decode + TGP_T_SETS DW ? ; Saved Charset Segment + TGP_T_SETO DW ? ; Saved Charset Offset + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TGP_ColorF DB ?,? ; Text Color + TGP_Ypos DW ? ; Y Position to Print at + TGP_Xpos DW ? ; X position to Print at + TGP_Char DB ?,? ; Character to Print +TGP_STACK ENDS + + PUBLIC TGPRINTC + +TGPRINTC PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 8 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + MOV AX, SCREEN_WIDTH ; Get Logical Line Width + MOV BX, AX ; BX = Screen Width + DEC BX ; = Screen Width-1 + MOV [BP].TGP_Width, BX ; Save for later use + + MUL [BP].TGP_Ypos ; Start of Line = Ypos * Width + ADD DI, AX ; DI -> Start of Line Ypos + + MOV AX, [BP].TGP_Xpos ; Get Xpos of Character + MOV CX, AX ; Save Copy of Xpos + SHR AX, 1 ; Bytes into Line = Xpos/4 + SHR AX, 1 ; Bytes into Line = Xpos/4 + ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + MOV AL, [BP].TGP_Char ; Get Character # + TEST AL, 080h ; Is Hi Bit Set? + JZ @TGP_LowChar ; Nope, use low char set ptr + + AND AL, 07Fh ; Mask Out Hi Bit + MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + JMP s @TGP_Set_Char ; Go Setup Character Ptr + +@TGP_LowChar: + + MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + +@TGP_Set_Char: + MOV [BP].TGP_T_SETS, DX ; Save Segment on Stack + + MOV AH, 0 ; Valid #'s are 0..127 + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + SHL AX, 1 ; * 8 Bytes Per Bitmap + ADD BX, AX ; BX = Offset of Selected char + MOV [BP].TGP_T_SETO, BX ; Save Offset on Stack + + AND CX, PLANE_BITS ; Get Plane # + MOV CH, ALL_PLANES ; Get Initial Plane mask + SHL CH, CL ; And shift into position + AND CH, ALL_PLANES ; And mask to lower nibble + + MOV AL, 04 ; 4-Plane # = # of initial + SUB AL, CL ; shifts to align bit mask + MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + INC DX ; DX -> SC_Data + + MOV AL, 08 ; 8 Lines to Process + MOV [BP].TGP_Lines, AL ; Save on Stack + + MOV DS, [BP].TGP_T_SETS ; Point to character set + +@TGP_DECODE_CHAR_BYTE: + + MOV SI, [BP].TGP_T_SETO ; Get DS:SI = String + + MOV BH, [SI] ; Get Bit Map + INC SI ; Point to Next Line + MOV [BP].TGP_T_SETO, SI ; And save new Pointer... + + MOV AH, [BP].TGP_ColorF ; Get Foreground Color + + mov bl,0 ; Clear BL + ROL BX, CL ; BL holds left edge bits + MOV SI, BX ; Use as Table Index + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_LEFT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + +@TGP_NO_LEFT1BITS: + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_MIDDLE1BITS ; Skip if no pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_MIDDLE1BITS: + XOR CH, ALL_PLANES ; Invert Clip Mask + CMP CL, 4 ; Aligned by 4? + JZ @TGP_NEXT_LINE ; If so, Exit now.. + + INC DI ; Point to next Byte + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + ROL BX, 1 ; Shift 4 bits + + MOV SI, BX ; Make Lookup Pointer + AND SI, CHAR_BITS ; Get Low Bits + MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + JZ @TGP_NO_RIGHT1BITS ; Skip if No Pixels to set + + OUT DX, AL ; Set up Screen Mask + MOV ES:[DI], AH ; Write Foreground color + +@TGP_NO_RIGHT1BITS: + + DEC DI ; Adjust for Next Line Advance + +@TGP_NEXT_LINE: + ADD DI, [BP].TGP_Width ; Point to Next Line + XOR CH, CHAR_BITS ; Flip the Clip mask back + + DEC [BP].TGP_Lines ; Count Down Lines + JZ @TGP_EXIT ; Ok... Done! + + JMP @TGP_DECODE_CHAR_BYTE ; Again! Hey! + +@TGP_EXIT: + ADD SP, 08 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 8 ; Exit and Clean up Stack + +TGPRINTC ENDP + + +;=============================================================== +;PRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;=============================================================== +; +; Routine to quickly Print a null terminated ASCII string on the +; active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; ColorB = Color to set background to +; +; EXIT: No meaningful values returned +; + +PS_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + PS_ColorB DW ? ; Background Color + PS_ColorF DW ? ; Text Color + PS_Ypos DW ? ; Y Position to Print at + PS_Xpos DW ? ; X position to Print at + PS_Len DW ? ; Maximum Length of string to print + PS_Text DW ?,? ; Far Ptr to Text String +PS_STACK ENDS + + PUBLIC PRINT_STR + +PRINT_STR PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + +@PS_Print_It: + + MOV CX, [BP].PS_Len ; Get Remaining text Length + JCXZ @PS_Exit ; Exit when out of text + + LES DI, d [BP].PS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @PS_Exit ; Exit if null character + + DEC [BP].PS_Len ; Remaining Text length-- + INC [BP].PS_Text ; Point to Next text char + + ; Set up Call to GPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].PS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].PS_Xpos, BX ; Save for next time through + + MOV BX, [BP].PS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].PS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + MOV BX, [BP].PS_ColorB ; Get Background Color + PUSH BX ; Set ColorB Parameter + + CALL f GPRINTC ; Print Character! + JMP s @PS_Print_It ; Process next character + +@PS_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 14 ; Exit and Clean up Stack + +PRINT_STR ENDP + + +;================================================================ +;TPRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) +;================================================================ +; +; Routine to quickly transparently Print a null terminated ASCII +; string on the active display page up to a maximum length. +; +; ENTRY: String = Far Pointer to ASCII string to print +; MaxLen = # of characters to print if no null found +; Xpos = X position to draw Text at +; Ypos = Y position of to draw Text at +; ColorF = Color to draw text in +; +; EXIT: No meaningful values returned +; + +TPS_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TPS_ColorF DW ? ; Text Color + TPS_Ypos DW ? ; Y Position to Print at + TPS_Xpos DW ? ; X position to Print at + TPS_Len DW ? ; Maximum Length of string to print + TPS_Text DW ?,? ; Far Ptr to Text String +TPS_STACK ENDS + + PUBLIC TPRINT_STR + +TPRINT_STR PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + +@TPS_Print_It: + + MOV CX, [BP].TPS_Len ; Get Remaining text Length + JCXZ @TPS_Exit ; Exit when out of text + + LES DI, d [BP].TPS_Text ; ES:DI -> Current Char in Text + MOV AL, ES:[DI] ; AL = Text Character + AND AX, 00FFh ; Clear High Word + JZ @TPS_Exit ; Exit if null character + + DEC [BP].TPS_Len ; Remaining Text length-- + INC [BP].TPS_Text ; Point to Next text char + + ; Set up Call to TGPRINTC + + PUSH AX ; Set Character Parameter + MOV BX, [BP].TPS_Xpos ; Get Xpos + PUSH BX ; Set Xpos Parameter + ADD BX, 8 ; Advance 1 Char to Right + MOV [BP].TPS_Xpos, BX ; Save for next time through + + MOV BX, [BP].TPS_Ypos ; Get Ypos + PUSH BX ; Set Ypos Parameter + + MOV BX, [BP].TPS_ColorF ; Get Text Color + PUSH BX ; Set ColorF Parameter + + CALL f TGPRINTC ; Print Character! + JMP s @TPS_Print_It ; Process next character + +@TPS_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +TPRINT_STR ENDP + + +;=========================================== +;SET_DISPLAY_FONT(SEG FontData, FontNumber%) +;=========================================== +; +; Allows the user to specify their own font data for +; wither the lower or upper 128 characters. +; +; ENTRY: FontData = Far Pointer to Font Bitmaps +; FontNumber = Which half of set this is +; = 0, Lower 128 characters +; = 1, Upper 128 characters +; +; EXIT: No meaningful values returned +; + +SDF_STACK STRUC + DW ? ; BP + DD ? ; Caller + SDF_Which DW ? ; Hi Table/Low Table Flag + SDF_Font DD ? ; Far Ptr to Font Table +SDF_STACK ENDS + + PUBLIC SET_DISPLAY_FONT + +SET_DISPLAY_FONT PROC FAR + + PUSH BP ; Preserve Registers + MOV BP, SP ; Set up Stack Frame + + LES DI, [BP].SDF_Font ; Get Far Ptr to Font + + MOV SI, o CHARSET_LOW ; Assume Lower 128 chars + TEST [BP].SDF_Which, 1 ; Font #1 selected? + JZ @SDF_Set_Font ; If not, skip ahead + + MOV SI, o CHARSET_HI ; Ah, really it's 128-255 + +@SDF_Set_Font: + MOV [SI], DI ; Set Font Pointer Offset + MOV [SI+2], ES ; Set Font Pointer Segment + + POP BP ; Restore Registers + RET 6 ; We are Done.. Outa here + +SET_DISPLAY_FONT ENDP + + + ; ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +;====================================================== +;DRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;====================================================== +; +; Draws a variable sized Graphics Bitmap such as a +; picture or an Icon on the current Display Page in +; Mode X. The Bitmap is stored in a linear byte array +; corresponding to (0,0) (1,0), (2,0) .. (Width, Height) +; This is the same linear manner as mode 13h graphics. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +DB_STACK STRUC + DB_LineO DW ? ; Offset to Next Line + DB_PixCount DW ? ; (Minimum) # of Pixels/Line + DB_Start DW ? ; Addr of Upper Left Pixel + DB_PixSkew DW ? ; # of bytes to Adjust EOL + DB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + DB_Height DW ? ; Height of Bitmap in Pixels + DB_Width DW ? ; Width of Bitmap in Pixels + DB_Ypos DW ? ; Y position to Draw Bitmap at + DB_Xpos DW ? ; X position to Draw Bitmap at + DB_Image DD ? ; Far Pointer to Graphics Bitmap +DB_STACK ENDS + + PUBLIC DRAW_BITMAP + +DRAW_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].DB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].DB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 1 ; Xpos/4 = Offset Into Line + SHR BX, 1 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].DB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].DB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 1 ; /4 = width in bands + SHR BX, 1 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].DB_LineO, AX ; Save Line Width offset + MOV [BP].DB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].DB_PixSkew, DX ; Also End of Line Skew + MOV [BP].DB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@DB_COPY_PLANE: + + LDS SI, [BP].DB_Image ; DS:SI-> Source Image + MOV DX, [BP].DB_Height ; # of Lines to Copy + MOV DI, [BP].DB_Start ; ES:DI-> Dest pos + +@DB_COPY_LINE: + MOV CX, [BP].DB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @DB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@DB_COPY_LOOP: + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + MOVSB ; Copy Bitmap Pixel + ADD SI, 3 ; Skip to Next Byte in same plane + + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @DB_COPY_LOOP ; if so, do another block + +@DB_COPY_REMAINDER: + JCXZ @DB_NEXT_LINE ; Any Pixels left on line + +@DB_COPY2: + MOVSB ; Copy Bitmap Pixel + ADD SI,3 ; Skip to Next Byte in same plane + LOOPx CX, @DB_COPY2 ; Pixels to Copy--, Loop until done + +@DB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].DB_SkewFlag ; Get Skew Count + JZ @DB_NEXT2 ; if no partial pixels + + MOVSB ; Copy Bitmap Pixel + DEC DI ; Back up to align + DEC SI ; Back up to align + +@DB_NEXT2: + ADD SI, [BP].DB_PixSkew ; Adjust Skew + ADD DI, [BP].DB_LineO ; Set to Next Display Line + LOOPx DX, @DB_COPY_LINE ; Lines to Copy--, Loop if more + + ; Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @DB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].DB_Start, 0 ; Screen Addr =+Carry + INC w [BP].DB_Image ; Start @ Next Byte + + SUB [BP].DB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].DB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP s @DB_COPY_PLANE ; Go Copy the Next Plane + +@DB_Exit: + ADD SP, 10 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +DRAW_BITMAP ENDP + + +;======================================================= +;TDRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) +;======================================================= +; +; Transparently Draws a variable sized Graphics Bitmap +; such as a picture or an Icon on the current Display Page +; in Mode X. Pixels with a value of 0 are not drawn, +; leaving the previous "background" contents intact. +; +; The Bitmap format is the same as for the DRAW_BITMAP function. +; +; ENTRY: Image = Far Pointer to Bitmap Data +; Xpos = X position to Place Upper Left pixel at +; Ypos = Y position to Place Upper Left pixel at +; Width = Width of the Bitmap in Pixels +; Height = Height of the Bitmap in Pixels +; +; EXIT: No meaningful values returned +; + +TB_STACK STRUC + TB_LineO DW ? ; Offset to Next Line + TB_PixCount DW ? ; (Minimum) # of Pixels/Line + TB_Start DW ? ; Addr of Upper Left Pixel + TB_PixSkew DW ? ; # of bytes to Adjust EOL + TB_SkewFlag DW ? ; Extra Pix on Plane Flag + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + TB_Height DW ? ; Height of Bitmap in Pixels + TB_Width DW ? ; Width of Bitmap in Pixels + TB_Ypos DW ? ; Y position to Draw Bitmap at + TB_Xpos DW ? ; X position to Draw Bitmap at + TB_Image DD ? ; Far Pointer to Graphics Bitmap +TB_STACK ENDS + + PUBLIC TDRAW_BITMAP + +TDRAW_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 10 ; Allocate workspace + MOV BP, SP ; Set up Stack Frame + + LES DI, d CURRENT_PAGE ; Point to Active VGA Page + CLD ; Direction Flag = Forward + + MOV AX, [BP].TB_Ypos ; Get UL Corner Ypos + MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + MOV BX, [BP].TB_Xpos ; Get UL Corner Xpos + MOV CL, BL ; Save Plane # in CL + SHR BX, 1 ; Xpos/4 = Offset Into Line + SHR BX, 1 ; Xpos/4 = Offset Into Line + + ADD DI, AX ; ES:DI -> Start of Line + ADD DI, BX ; ES:DI -> Upper Left Pixel + MOV [BP].TB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + MOV BX, [BP].TB_Width ; Get Width of Image + MOV DX, BX ; Save Copy in DX + SHR BX, 1 ; /4 = width in bands + SHR BX, 1 ; /4 = width in bands + MOV AX, SCREEN_WIDTH ; Get Screen Width + SUB AX, BX ; - (Bitmap Width/4) + + MOV [BP].TB_LineO, AX ; Save Line Width offset + MOV [BP].TB_PixCount, BX ; Minimum # pix to copy + + AND DX, PLANE_BITS ; Get "partial band" size (0-3) + MOV [BP].TB_PixSkew, DX ; Also End of Line Skew + MOV [BP].TB_SkewFlag, DX ; Save as Flag/Count + + AND CX, PLANE_BITS ; CL = Starting Plane # + MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + MOV BH, AH ; BH = Saved Plane Mask + MOV BL, 4 ; BL = Planes to Copy + +@TB_COPY_PLANE: + + LDS SI, [BP].TB_Image ; DS:SI-> Source Image + MOV DX, [BP].TB_Height ; # of Lines to Copy + MOV DI, [BP].TB_Start ; ES:DI-> Dest pos + + ; Here AH is set with the value to be considered + ; "Transparent". It can be changed! + + MOV AH, 0 ; Value to Detect 0 + +@TB_COPY_LINE: + MOV CX, [BP].TB_PixCount ; Min # to copy + + TEST CL, 0FCh ; 16+PixWide? + JZ @TB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + +@TB_COPY_LOOP: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_01 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_01: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_02 ; Skip ahead if so + MOV ES:[DI+1], AL ; Copy Pixel to VGA screen + +@TB_SKIP_02: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_03 ; Skip ahead if so + MOV ES:[DI+2], AL ; Copy Pixel to VGA screen + +@TB_SKIP_03: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_04 ; Skip ahead if so + MOV ES:[DI+3], AL ; Copy Pixel to VGA screen + +@TB_SKIP_04: + ADD DI, 4 ; Adjust Pixel Write Location + SUB CL, 4 ; Pixels to Copy=-4 + TEST CL, 0FCh ; 4+ Pixels Left? + JNZ @TB_COPY_LOOP ; if so, do another block + +@TB_COPY_REMAINDER: + JCXZ @TB_NEXT_LINE ; Any Pixels left on line + +@TB_COPY2: + LODSB ; Get Pixel Value in AL + ADD SI, 3 ; Skip to Next Byte in same plane + CMP AL, AH ; It is "Transparent"? + JE @TB_SKIP_05 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_SKIP_05: + INC DI ; Advance Dest Addr + LOOPx CX, @TB_COPY2 ; Pixels to Copy--, Loop until done + +@TB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + OR CX, [BP].TB_SkewFlag ; Get Skew Count + JZ @TB_NEXT2 ; if no partial pixels + + LODSB ; Get Pixel Value in AL + DEC SI ; Backup to Align + CMP AL, AH ; It is "Transparent"? + JE @TB_NEXT2 ; Skip ahead if so + MOV ES:[DI], AL ; Copy Pixel to VGA screen + +@TB_NEXT2: + ADD SI, [BP].TB_PixSkew ; Adjust Skew + ADD DI, [BP].TB_LineO ; Set to Next Display Line + LOOPx DX, @TB_COPY_LINE ; Lines to Copy--, Loop if More + + ;Copy Next Plane.... + + DEC BL ; Planes to Go-- + JZ @TB_Exit ; Hey! We are done + + ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + + CMP AL, 12h ; Carry Set if AL=11h + ADC [BP].TB_Start, 0 ; Screen Addr =+Carry + INC w [BP].TB_Image ; Start @ Next Byte + + SUB [BP].TB_SkewFlag, 1 ; Reduce Planes to Skew + ADC [BP].TB_SkewFlag, 0 ; Back to 0 if it was -1 + + JMP @TB_COPY_PLANE ; Go Copy the next Plane + +@TB_Exit: + ADD SP, 10 ; Deallocate workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 12 ; Exit and Clean up Stack + +TDRAW_BITMAP ENDP + + + ; ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +;================================== +;COPY_PAGE (SourcePage%, DestPage%) +;================================== +; +; Duplicate on display page onto another +; +; ENTRY: SourcePage = Display Page # to Duplicate +; DestPage = Display Page # to hold copy +; +; EXIT: No meaningful values returned +; + +CP_STACK STRUC + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + CP_DestP DW ? ; Page to hold copied image + CP_SourceP DW ? ; Page to Make copy from +CP_STACK ENDS + + PUBLIC COPY_PAGE + +COPY_PAGE PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + MOV BP, SP ; Set up Stack Frame + CLD ; Block Xfer Forwards + + ; Make sure Page #'s are valid + + MOV AX, [BP].CP_SourceP ; Get Source Page # + CMP AX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + MOV BX, [BP].CP_DestP ; Get Destination Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CP_Exit ; if so, abort + + CMP AX, BX ; Pages #'s the same? + JE @CP_Exit ; if so, abort + + ; Setup DS:SI and ES:DI to Video Pages + + SHL BX, 1 ; Scale index to Word + MOV DI, PAGE_ADDR[BX] ; Offset to Dest Page + + MOV BX, AX ; Index to Source page + SHL BX, 1 ; Scale index to Word + MOV SI, PAGE_ADDR[BX] ; Offset to Source Page + + MOV CX, PAGE_SIZE ; Get size of Page + MOV AX, CURRENT_SEGMENT ; Get Video Mem Segment + MOV ES, AX ; ES:DI -> Dest Page + MOV DS, AX ; DS:SI -> Source Page + + ; Setup VGA registers for Mem to Mem copy + + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + OUT_16 SC_Index, ALL_PLANES_ON ; Copy all Planes + + ; Note.. Do *NOT* use MOVSW or MOVSD - they will + ; Screw with the latches which are 8 bits x 4 + + REP MOVSB ; Copy entire Page! + + ; Reset VGA for normal memory access + + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = off + +@CP_Exit: + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 4 ; Exit and Clean up Stack + +COPY_PAGE ENDP + + +;========================================================================== +;COPY_BITMAP (SourcePage%, X1%, Y1%, X2%, Y2%, DestPage%, DestX1%, DestY1%) +;========================================================================== +; +; Copies a Bitmap Image from one Display Page to Another +; This Routine is Limited to copying Images with the same +; Plane Alignment. To Work: (X1 MOD 4) must = (DestX1 MOD 4) +; Copying an Image to the Same Page is supported, but results +; may be defined when the when the rectangular areas +; (X1, Y1) - (X2, Y2) and (DestX1, DestY1) - +; (DestX1+(X2-X1), DestY1+(Y2-Y1)) overlap... +; No Paramter checking to done to insure that +; X2 >= X1 and Y2 >= Y1. Be Careful... +; +; ENTRY: SourcePage = Display Page # with Source Image +; X1 = Upper Left Xpos of Source Image +; Y1 = Upper Left Ypos of Source Image +; X2 = Lower Right Xpos of Source Image +; Y2 = Lower Right Ypos of Source Image +; DestPage = Display Page # to copy Image to +; DestX1 = Xpos to Copy UL Corner of Image to +; DestY1 = Ypos to Copy UL Corner of Image to +; +; EXIT: AX = Success Flag: 0 = Failure / -1= Success +; + +CB_STACK STRUC + CB_Height DW ? ; Height of Image in Lines + CB_Width DW ? ; Width of Image in "bands" + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DI, SI, DS, BP + DW ?x1 ; DS, DI, SI, BP + DW ?x1 ; DS, DI, SI, BP + DD ? ; Caller + CB_DestY1 DW ? ; Destination Ypos + CB_DestX1 DW ? ; Destination Xpos + CB_DestP DW ? ; Page to Copy Bitmap To + CB_Y2 DW ? ; LR Ypos of Image + CB_X2 DW ? ; LR Xpos of Image + CB_Y1 DW ? ; UL Ypos of Image + CB_X1 DW ? ; UL Xpos of Image + CB_SourceP DW ? ; Page containing Source Bitmap +CB_STACK ENDS + + PUBLIC COPY_BITMAP + +COPY_BITMAP PROC FAR + + ;PUSHx BP, DS, SI, DI ; Preserve Important Registers + push bp + push ds + push si + push di + SUB SP, 4 ; Allocate WorkSpace on Stack + MOV BP, SP ; Set up Stack Frame + + ; Prep Registers (and keep jumps short!) + + MOV ES, CURRENT_SEGMENT ; ES -> VGA Ram + CLD ; Block Xfer Forwards + + ; Make sure Parameters are valid + + MOV BX, [BP].CB_SourceP ; Get Source Page # + CMP BX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV CX, [BP].CB_DestP ; Get Destination Page # + CMP CX, LAST_PAGE ; is it > Max Page #? + JAE @CB_Abort ; if so, abort + + MOV AX, [BP].CB_X1 ; Get Source X1 + XOR AX, [BP].CB_DestX1 ; Compare Bits 0-1 + AND AX, PLANE_BITS ; Check Plane Bits + JNZ @CB_Abort ; They should cancel out + + ; Setup for Copy processing + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + + ; Compute Info About Images, Setup ES:SI & ES:DI + + MOV AX, [BP].CB_Y2 ; Height of Bitmap in lines + SUB AX, [BP].CB_Y1 ; is Y2 - Y1 + 1 + INC AX ; (add 1 since were not 0 based) + MOV [BP].CB_Height, AX ; Save on Stack for later use + + MOV AX, [BP].CB_X2 ; Get # of "Bands" of 4 Pixels + MOV DX, [BP].CB_X1 ; the Bitmap Occupies as X2-X1 + SHR AX, 1 ; Get X2 Band (X2 / 4) + SHR DX, 1 ; Get X1 Band (X1 / 4) + SHR AX, 1 ; Get X2 Band (X2 / 4) + SHR DX, 1 ; Get X1 Band (X1 / 4) + SUB AX, DX ; AX = # of Bands - 1 + INC AX ; AX = # of Bands + MOV [BP].CB_Width, AX ; Save on Stack for later use + + SHL BX, 1 ; Scale Source Page to Word + MOV SI, PAGE_ADDR[BX] ; SI = Offset of Source Page + MOV AX, [BP].CB_Y1 ; Get Source Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD SI, AX ; SI = Offset to Line Y1 + MOV AX, [BP].CB_X1 ; Get Source X1 + SHR AX, 1 ; X1 / 4 = Byte offset + SHR AX, 1 ; X1 / 4 = Byte offset + ADD SI, AX ; SI = Byte Offset to (X1,Y1) + + MOV BX, CX ; Dest Page Index to BX + SHL BX, 1 ; Scale Source Page to Word + MOV DI, PAGE_ADDR[BX] ; DI = Offset of Dest Page + MOV AX, [BP].CB_DestY1 ; Get Dest Y1 Line + MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + ADD DI, AX ; DI = Offset to Line Y1 + MOV AX, [BP].CB_DestX1 ; Get Dest X1 + SHR AX, 1 ; X1 / 4 = Byte offset + SHR AX, 1 ; X1 / 4 = Byte offset + ADD DI, AX ; DI = Byte Offset to (D-X1,D-Y1) + + MOV CX, [BP].CB_Width ; CX = Width of Image (Bands) + DEC CX ; CX = 1? + JE @CB_Only_One_Band ; 0 Means Image Width of 1 Band + + MOV BX, [BP].CB_X1 ; Get Source X1 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 00?) + JZ @CB_Check_Right ; if so, check right alignment + JNZ @CB_Left_Band ; not aligned? well.. + +@CB_Abort: + mov ax,0 ; Return False (Failure) + JMP @CB_Exit ; and Finish Up + + ; Copy when Left & Right Clip Masks overlap... + +@CB_Only_One_Band: + MOV BX, [BP].CB_X1 ; Get Left Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + MOV AL, Left_Clip_Mask[BX] ; Get Left Edge Mask + MOV BX, [BP].CB_X2 ; Get Right Clip Mask + AND BX, PLANE_BITS ; Mask out Row # + AND AL, Right_Clip_Mask[BX] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + mov bx,0 ; BX = Offset into Image + +@CB_One_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_One_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_One_Loop ; Loop until Finished + +@CB_One_Done: + JMP @CB_Finish ; Outa Here! + + ; Copy Left Edge of Bitmap + +@CB_Left_Band: + + OUT_8 SC_Data, Left_Clip_Mask[BX] ; Set Left Edge Plane Mask + + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + mov bx,0 ; BX = Offset into Image + +@CB_Left_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Left_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Left_Loop ; Loop until Finished + +@CB_Left_Done: + INC DI ; Move Dest Over 1 band + INC SI ; Move Source Over 1 band + DEC [BP].CB_Width ; Band Width-- + + ; Determine if Right Edge of Bitmap needs special copy + +@CB_Check_Right: + MOV BX, [BP].CB_X2 ; Get Source X2 + AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 11?) + CMP BL, 03h ; Plane = 3? + JE @CB_Copy_Middle ; Copy the Middle then! + + ; Copy Right Edge of Bitmap + +@CB_Right_Band: + + OUT_8 SC_Data, Right_Clip_Mask[BX] ; Set Right Edge Plane Mask + + DEC [BP].CB_Width ; Band Width-- + MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + MOV DX, SCREEN_WIDTH ; DX = Width of Screen + MOV BX, [BP].CB_Width ; BX = Offset to Right Edge + +@CB_Right_Loop: + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Right_Done ; Exit Loop if Finished + + MOV AL, ES:[SI+BX] ; Load Latches + MOV ES:[DI+BX], AL ; Unload Latches + ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Right_Loop ; Loop until Finished + +@CB_Right_Done: + + ; Copy the Main Block of the Bitmap + +@CB_Copy_Middle: + + MOV CX, [BP].CB_Width ; Get Width Remaining + JCXZ @CB_Finish ; Exit if Done + + OUT_8 SC_Data, ALL_PLANES ; Copy all Planes + + MOV DX, SCREEN_WIDTH ; Get Width of Screen minus + SUB DX, CX ; Image width (for Adjustment) + MOV AX, [BP].CB_Height ; AX = # of Lines to Copy + MOV BX, CX ; BX = Quick REP reload count + MOV CX, ES ; Move VGA Segment + MOV DS, CX ; Into DS + + ; Actual Copy Loop. REP MOVSB does the work + +@CB_Middle_Copy: + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + LOOPjz AX, @CB_Finish ; Exit Loop if Finished + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + + MOV CX, BX ; Recharge Rep Count + REP MOVSB ; Move Bands + + ADD SI, DX ; Adjust DS:SI to Next Line + ADD DI, DX ; Adjust ES:DI to Next Line + LOOPx AX, @CB_Middle_Copy ; Copy Lines until Done + +@CB_Finish: + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = on + +@CB_Exit: + ADD SP, 04 ; Deallocate stack workspace + ;POPx DI, SI, DS, BP ; Restore Saved Registers + pop di + pop si + pop ds + pop bp + RET 16 ; Exit and Clean up Stack + +COPY_BITMAP ENDP + + END ; End of Code Segment diff --git a/src/lib/modex/modex.bi b/src/lib/modex/modex.bi new file mode 100755 index 00000000..6b1d7afe --- /dev/null +++ b/src/lib/modex/modex.bi @@ -0,0 +1,63 @@ + + ' ===== SCREEN RESOLUTIONS ===== + +CONST Mode320x200 = 0, Mode320x400 = 1 +CONST Mode360x200 = 2, Mode360x400 = 3 +CONST Mode320x240 = 4, Mode320x480 = 5 +CONST Mode360x240 = 6, Mode360x480 = 7 + + ' ===== MODE X SETUP ROUTINES ===== + +DECLARE FUNCTION SET.VGA.MODEX% ALIAS "SET_VGA_MODEX" (BYVAL ModeType%, BYVAL MaxXpos%, BYVAL MaxYpos%, BYVAL Pages%) +DECLARE FUNCTION SET.MODEX% ALIAS "SET_MODEX" (BYVAL Mode%) + + ' ===== BASIC GRAPHICS PRIMITIVES ===== + +DECLARE SUB CLEAR.VGA.SCREEN ALIAS "CLEAR_VGA_SCREEN" (BYVAL ColorNum%) +DECLARE SUB SET.POINT ALIAS "SET_POINT" (BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorNum%) +DECLARE FUNCTION READ.POINT% ALIAS "READ_POINT" (BYVAL Xpos%, BYVAL Ypos%) +DECLARE SUB FILL.BLOCK ALIAS "FILL_BLOCK" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) +DECLARE SUB DRAW.LINE ALIAS "DRAW_LINE" (BYVAL Xpos1%, BYVAL Ypos1%, BYVAL Xpos2%, BYVAL Ypos2%, BYVAL ColorNum%) + + ' ===== DAC COLOR REGISTER ROUTINES ===== + +DECLARE SUB SET.DAC.REGISTER ALIAS "SET_DAC_REGISTER" (BYVAL RegNo%, BYVAL Red%, BYVAL Green%, BYVAL Blue%) +DECLARE SUB GET.DAC.REGISTER ALIAS "GET_DAC_REGISTER" (BYVAL RegNo%, Red%, Green%, Blue%) +DECLARE SUB LOAD.DAC.REGISTERS ALIAS "LOAD_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%, BYVAL VSync%) +DECLARE SUB READ.DAC.REGISTERS ALIAS "READ_DAC_REGISTERS" (SEG PalData AS ANY, BYVAL StartReg%, BYVAL EndReg%) + + + ' ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + +DECLARE SUB SET.ACTIVE.PAGE ALIAS "SET_ACTIVE_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.ACTIVE.PAGE% ALIAS "GET_ACTIVE_PAGE" +DECLARE SUB SET.DISPLAY.PAGE ALIAS "SET_DISPLAY_PAGE" (BYVAL PageNo%) +DECLARE FUNCTION GET.DISPLAY.PAGE% ALIAS "GET_DISPLAY_PAGE" +DECLARE SUB SET.WINDOW ALIAS "SET_WINDOW" (BYVAL DisplayPage%, BYVAL XOffset%, BYVAL YOffset%) +DECLARE FUNCTION GET.X.OFFSET% ALIAS "GET_X_OFFSET" () +DECLARE FUNCTION GET.Y.OFFSET% ALIAS "GET_Y_OFFSET" () +DECLARE SUB SYNC.DISPLAY ALIAS "SYNC_DISPLAY" + + ' ===== TEXT DISPLAY ROUTINES ===== + +DECLARE SUB GPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TGPRINTC (BYVAL CharacterNum%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB PRINT.STR ALIAS "PRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%, BYVAL ColorB%) +DECLARE SUB TPRINT.STR ALIAS "TPRINT_STR" (BYVAL StrSeg%, BYVAL StrOfs%, BYVAL MaxLen%, BYVAL Xpos%, BYVAL Ypos%, BYVAL ColorF%) +DECLARE SUB SET.DISPLAY.FONT ALIAS "SET_DISPLAY_FONT" (SEG FontData AS ANY, BYVAL FontNumber%) + + ' ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + +DECLARE SUB DRAW.BITMAP ALIAS "DRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) +DECLARE SUB TDRAW.BITMAP ALIAS "TDRAW_BITMAP" (SEG Image AS ANY, BYVAL Xpos%, BYVAL Ypos%, BYVAL xWidth%, BYVAL Height%) + + ' ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + +DECLARE SUB COPY.PAGE ALIAS "COPY_PAGE" (BYVAL SourcePage%, BYVAL DestPage%) +DECLARE SUB COPY.BITMAP ALIAS "COPY_BITMAP" (BYVAL SourcePage%, BYVAL X1%, BYVAL Y1%, BYVAL X2%, BYVAL Y2%, BYVAL DestPage%, BYVAL DestX1%, BYVAL DestY1%) + + + + + + diff --git a/src/lib/modex/modex.h b/src/lib/modex/modex.h new file mode 100755 index 00000000..1381abb6 --- /dev/null +++ b/src/lib/modex/modex.h @@ -0,0 +1,76 @@ + +#ifndef __MODEX_H +#define __MODEX_H + + /* ===== SCREEN RESOLUTIONS ===== */ + +#define Mode_320x200 0 +#define Mode_320x400 1 +#define Mode_360x200 2 +#define Mode_360x400 3 +#define Mode_320x240 4 +#define Mode_320x480 5 +#define Mode_360x240 6 +#define Mode_360x480 7 + + /* ===== MODE X SETUP ROUTINES ===== */ + +int far pascal set_vga_modex (int Mode, int MaxXpos, int MaxYpos, int Pages); +int far pascal set_modex (int Mode); + + /* ===== BASIC GRAPHICS PRIMITIVES ===== */ + +void far pascal clear_vga_screen (int Color); +void far pascal set_point (int Xpos, int Ypos, int Color); +int far pascal read_point (int Xpos, int Ypos); +void far pascal fill_block (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); +void far pascal draw_line (int Xpos1, int Ypos1, int Xpos2, int Ypos2, + int Color); + + /* ===== DAC COLOR REGISTER ROUTINES ===== */ + +void far pascal set_dac_register (int RegNo, int Red, int Green, int Blue); +void far pascal get_dac_register (int RegNo, int* Red, int* Green, int* Blue); +void far pascal load_dac_registers (char far *PalData, int StartReg, + int EndReg, int VSync); +void far pascal readd_dac_registers (char far *PalData, int StartReg, + int EndReg); + + /* ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== */ + +void far pascal set_active_page (int PageNo); +int far pascal get_active_page (void); +void far pascal set_display_page (int PageNo); +int far pascal get_display_page (void); +void far pascal set_window (int DisplayPage, int XOffset, int YOffset); +int far pascal get_x_offset (void); +int far pascal get_y_offset (void); +void far pascal sync_display (void); + + /* ===== TEXT DISPLAY ROUTINES ===== */ + +void far pascal gprintc (int CharNum, int Xpos, int Ypos, int ColorF, + int ColorB); +void far pascal tgprintc (int CharNum, int Xpos, int Ypos, int ColorF); +void far pascal print_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF, int ColorB); +void far pascal tprint_str (char far *Text, int MaxLen, int Xpos, int Ypos, + int ColorF); +void far pascal set_display_font (char far *FontData, int FontNumber); + + /* ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== */ + +void far pascal draw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); +void far pascal tdraw_bitmap (char far *Image, int Xpos, int Ypos, + int Width, int Height); + + /* ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== */ + +void far pascal copy_page (int SourcePage, int DestPage); +void far pascal copy_bitmap (int SourcePage, int X1, int Y1, int X2, int Y2, + int DestPage, int DestX1, int DestY1); + + +#endif diff --git a/src/lib/modex/modex.lst b/src/lib/modex/modex.lst new file mode 100755 index 00000000..ce6d955c --- /dev/null +++ b/src/lib/modex/modex.lst @@ -0,0 +1,4122 @@ +Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 1 - 1 + + + ;======================================================== + ; MODEX.ASM - A Complete Mode X Library + ; + ; Version 1.04 Release, 3 May 1993, By Matt Pritchard + ; With considerable input from Michael Abrash + ; + ; The following information is donated to the public domain in + ; the hopes that save other programmers much frustration. + ; + ; If you do use this code in a product, it would be nice if + ; you include a line like "Mode X routines by Matt Pritchard" + ; in the credits. + ; + ; ========================================================= + ; + ; All of this code is designed to be assembled with MASM 5.10a + ; but TASM 3.0 could be used as well. + ; + ; The routines contained are designed for use in a MEDIUM model + ; program. All Routines are FAR, and is assumed that a DGROUP + ; data segment exists and that DS will point to it on entry. + ; + ; For all routines, the AX, BX, CX, DX, ES and FLAGS registers + ; will not be preserved, while the DS, BP, SI and DI registers + ; will be preserved. + ; + ; Unless specifically noted, All Parameters are assumed to be + ; "PASSED BY VALUE". That is, the actual value is placed on + ; the stack. When a reference is passed it is assumed to be + ; a near pointer to a variable in the DGROUP segment. + ; + ; Routines that return a single 16-Bit integer value will + ; return that value in the AX register. + ; + ; This code will *NOT* run on an 8086/8088 because 80286+ + ; specific instructions are used. If you have an 8088/86 + ; and VGA, you can buy an 80386-40 motherboard for about + ; $160 and move into the 90's. + ; + ; This code is reasonably optimized: Most drawing loops have + ; been unrolled once and memory references are minimized by + ; keeping stuff in registers when possible. + ; + ; Error Trapping varies by Routine. No Clipping is performed + ; so the caller should verify that all coordinates are valid. + ; + ; Several Macros are used to simplify common 2 or 3 instruction + ; sequences. Several Single letter Text Constants also + ; simplify common assembler expressions like "WORD PTR". + ; + ; ------------------ Mode X Variations ------------------ + ; + ; Mode # Screen Size Max Pages Aspect Ratio (X:Y) + ; + ; 0 320 x 200 4 Pages 1.2:1 + ; 1 320 x 400 2 Pages 2.4:1 + ; 2 360 x 200 3 Pages 1.35:1 + ; 3 360 x 400 1 Page 2.7:1 + ; 4 320 x 240 3 Pages 1:1 + ; 5 320 x 480 1 Page 2:1 + ; 6 360 x 240 3 Pages 1.125:1 + ; 7 360 x 480 1 Page 2.25:1 + ; + ; -------------------- The Legal Stuff ------------------ + ; + ; No warranty, either written or implied, is made as to + ; the accuracy and usability of this code product. Use + ; at your own risk. Batteries not included. Pepperoni + ; and extra cheese available for an additional charge. + ; + ; ----------------------- The Author -------------------- + ; + ; Matt Pritchard is a paid programmer who'd rather be + ; writing games. He can be reached at: P.O. Box 140264, + ; Irving, TX 75014 USA. Michael Abrash is a living + ; god, who now works for Bill Gates (Microsoft). + ; + ; -------------------- Revision History ----------------- + ; 4-12-93: v1.02 - SET_POINT & READ_POINT now saves DI + ; SET_MODEX now saves SI + ; 5-3-93: v1.04 - added LOAD_DAC_REGISTERS and + ; READ_DAC_REGISTERS. Expanded CLR Macro + ; to handle multiple registers + ; + + PAGE 255, 132 + + .MODEL Medium + .286 + + ; ===== MACROS ===== + + ; Macro to OUT a 16 bit value to an I/O port + + OUT_16 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AX not setup + MOV AX, Value ; then Get Data Value + ENDIF + OUT DX, AX ; Set I/O Register(s) + ENDM + + ; Macro to OUT a 8 bit value to an I/O Port + + OUT_8 MACRO Register, Value + IFDIFI , ; If DX not setup + MOV DX, Register ; then Select Register + ENDIF + IFDIFI , ; If AL not Setup + MOV AL, Value ; then Get Data Value + ENDIF + OUT DX, AL ; Set I/O Register + ENDM + + ; macros to PUSH and POP multiple registers + + PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + PUSH R1 ; Save R1 + PUSHx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8 + IFNB + POP R1 ; Restore R1 + POPx R2, R3, R4, R5, R6, R7, R8 + ENDIF + ENDM + + ; Macro to Clear Registers to 0 + + CLR MACRO Register, R2, R3, R4, R5, R6 + IFNB + XOR Register, Register ; Set Register = 0 + CLR R2, R3, R4, R5, R6 + ENDIF + ENDM + + ; Macros to Decrement Counter & Jump on Condition + + LOOPx MACRO Register, Destination + DEC Register ; Counter-- + JNZ Destination ; Jump if not 0 + ENDM + + LOOPjz MACRO Register, Destination + DEC Register ; Counter-- + JZ Destination ; Jump if 0 + ENDM + + + ; ===== General Constants ===== + + = 0000 False EQU 0 + =-0001 True EQU -1 + = 0000 nil EQU 0 + + = BYTE PTR b EQU BYTE PTR + = WORD PTR w EQU WORD PTR + = DWORD PTR d EQU DWORD PTR + = OFFSET o EQU OFFSET + = FAR PTR f EQU FAR PTR + = SHORT s EQU SHORT + = ?,?,?,? ?x4 EQU + = ?,?,? ?x3 EQU + + ; ===== VGA Register Values ===== + + = A000 VGA_Segment EQU 0A000h ; Vga Memory Segment + + = 03C0 ATTRIB_Ctrl EQU 03C0h ; VGA Attribute Controller + = 03CE GC_Index EQU 03CEh ; VGA Graphics Controller + = 03C4 SC_Index EQU 03C4h ; VGA Sequencer Controller + = 03C5 SC_Data EQU 03C5h ; VGA Sequencer Data Port + = 03D4 CRTC_Index EQU 03D4h ; VGA CRT Controller + = 03D5 CRTC_Data EQU 03D5h ; VGA CRT Controller Data + = 03C2 MISC_OUTPUT EQU 03C2h ; VGA Misc Register + = 03DA INPUT_1 EQU 03DAh ; Input Status #1 Register + + = 03C8 DAC_WRITE_ADDR EQU 03C8h ; VGA DAC Write Addr Register + = 03C7 DAC_READ_ADDR EQU 03C7h ; VGA DAC Read Addr Register + = 03C9 PEL_DATA_REG EQU 03C9h ; VGA DAC/PEL data Register R/W + + = 0033 PIXEL_PAN_REG EQU 033h ; Attrib Index: Pixel Pan Reg + = 0002 MAP_MASK EQU 002h ; Sequ Index: Write Map Mask reg + = 0004 READ_MAP EQU 004h ; GC Index: Read Map Register + = 000C START_DISP_HI EQU 00Ch ; CRTC Index: Display Start Hi + = 000D START_DISP_LO EQU 00Dh ; CRTC Index: Display Start Lo + + = 0102 MAP_MASK_PLANE1 EQU 00102h ; Map Register + Plane 1 + = 1102 MAP_MASK_PLANE2 EQU 01102h ; Map Register + Plane 1 + = 0F02 ALL_PLANES_ON EQU 00F02h ; Map Register + All Bit Planes + + = 0604 CHAIN4_OFF EQU 00604h ; Chain 4 mode Off + = 0100 ASYNC_RESET EQU 00100h ; (A)synchronous Reset + = 0300 SEQU_RESTART EQU 00300h ; Sequencer Restart + + = 0008 LATCHES_ON EQU 00008h ; Bit Mask + Data from Latches + = FF08 LATCHES_OFF EQU 0FF08h ; Bit Mask + Data from CPU + + = 0008 VERT_RETRACE EQU 08h ; INPUT_1: Vertical Retrace Bit + = 0003 PLANE_BITS EQU 03h ; Bits 0-1 of Xpos = Plane # + = 000F ALL_PLANES EQU 0Fh ; All Bit Planes Selected + = 000F CHAR_BITS EQU 0Fh ; Bits 0-3 of Character Data + + = 1130 GET_CHAR_PTR EQU 01130h ; VGA BIOS Func: Get Char Set + = 0003 ROM_8x8_Lo EQU 03h ; ROM 8x8 Char Set Lo Pointer + = 0004 ROM_8x8_Hi EQU 04h ; ROM 8x8 Char Set Hi Pointer + + ; Constants Specific for these routines + + = 0008 NUM_MODES EQU 8 ; # of Mode X Variations + + ; Specific Mode Data Table format... + + 000C Mode_Data_Table STRUC + 0000 00 M_MiscR DB ? ; Value of MISC_OUTPUT register + 0001 00 M_Pages DB ? ; Maximum Possible # of pages + 0002 0000 M_XSize DW ? ; X Size Displayed on screen + 0004 0000 M_YSize DW ? ; Y Size Displayed on screen + 0006 0000 M_XMax DW ? ; Maximum Possible X Size + 0008 0000 M_YMax DW ? ; Maximum Possible Y Size + 000A 0000 M_CRTC DW ? ; Table of CRTC register values + Mode_Data_Table ENDS + + ; ===== DGROUP STORAGE NEEDED (42 BYTES) ===== + + 0000 .DATA? + + 0000 0000 SCREEN_WIDTH DW 0 ; Width of a line in Bytes + 0002 0000 SCREEN_HEIGHT DW 0 ; Vertical Height in Pixels + + 0004 0000 LAST_PAGE DW 0 ; # of Display Pages + 0006 0004 [ PAGE_ADDR DW 4 DUP (0) ; Offsets to start of each page + 0000 + ] + + 000E 0000 PAGE_SIZE DW 0 ; Size of Page in Addr Bytes + + 0010 0000 DISPLAY_PAGE DW 0 ; Page # currently displayed + 0012 0000 ACTIVE_PAGE DW 0 ; Page # currently active + + 0014 0000 CURRENT_PAGE DW 0 ; Offset of current Page + 0016 0000 CURRENT_SEGMENT DW 0 ; Segment of VGA memory + + 0018 0000 CURRENT_XOFFSET DW 0 ; Current Display X Offset + 001A 0000 CURRENT_YOFFSET DW 0 ; Current Display Y Offset + + 001C 0000 CURRENT_MOFFSET DW 0 ; Current Start Offset + + 001E 0000 MAX_XOFFSET DW 0 ; Current Display X Offset + 0020 0000 MAX_YOFFSET DW 0 ; Current Display Y Offset + + 0022 0000 0000 CHARSET_LOW DW 0, 0 ; Far Ptr to Char Set: 0-127 + 0026 0000 0000 CHARSET_HI DW 0, 0 ; Far Ptr to Char Set: 128-255 + + 0000 .CODE + + ; ===== DATA TABLES ===== + + ; Data Tables, Put in Code Segment for Easy Access + ; (Like when all the other Segment Registers are in + ; use!!) and reduced DGROUP requirements... + + ; Bit Mask Tables for Left/Right/Character Masks + + 0000 0F 0E 0C 08 Left_Clip_Mask DB 0FH, 0EH, 0CH, 08H + + 0004 01 03 07 0F Right_Clip_Mask DB 01H, 03H, 07H, 0FH + + ; Bit Patterns for converting character fonts + + 0008 00 08 04 0C 02 0A Char_Plane_Data DB 00H,08H,04H,0CH,02H,0AH,06H,0EH + 06 0E + 0010 01 09 05 0D 03 0B DB 01H,09H,05H,0DH,03H,0BH,07H,0FH + 07 0F + + ; CRTC Register Values for Various Configurations + + 0018 MODE_Single_Line: ; CRTC Setup Data for 400/480 Line modes + 0018 4009 DW 04009H ; Cell Height (1 Scan Line) + 001A 0014 DW 00014H ; Dword Mode off + 001C E317 DW 0E317H ; turn on Byte Mode + 001E 0000 DW nil ; End of CRTC Data for 400/480 Line Mode + + 0020 MODE_Double_Line: ; CRTC Setup Data for 200/240 Line modes + 0020 4109 DW 04109H ; Cell Height (2 Scan Lines) + 0022 0014 DW 00014H ; Dword Mode off + 0024 E317 DW 0E317H ; turn on Byte Mode + 0026 0000 DW nil ; End of CRTC Data for 200/240 Line Mode + + 0028 MODE_320_Wide: ; CRTC Setup Data for 320 Horz Pixels + 0028 5F00 DW 05F00H ; Horz total + 002A 4F01 DW 04F01H ; Horz Displayed + 002C 5002 DW 05002H ; Start Horz Blanking + 002E 8203 DW 08203H ; End Horz Blanking + 0030 5404 DW 05404H ; Start H Sync + 0032 8005 DW 08005H ; End H Sync + 0034 0000 DW nil ; End of CRTC Data for 320 Horz pixels + + 0036 MODE_360_Wide: ; CRTC Setup Data for 360 Horz Pixels + 0036 6B00 DW 06B00H ; Horz total + 0038 5901 DW 05901H ; Horz Displayed + 003A 5A02 DW 05A02H ; Start Horz Blanking + 003C 8E03 DW 08E03H ; End Horz Blanking + 003E 5E04 DW 05E04H ; Start H Sync + 0040 8A05 DW 08A05H ; End H Sync + 0042 0000 DW nil ; End of CRTC Data for 360 Horz pixels + + 0044 MODE_200_Tall: + 0044 MODE_400_Tall: ; CRTC Setup Data for 200/400 Line modes + 0044 BF06 DW 0BF06H ; Vertical Total + 0046 1F07 DW 01F07H ; Overflow + 0048 9C10 DW 09C10H ; V Sync Start + 004A 8E11 DW 08E11H ; V Sync End/Prot Cr0 Cr7 + 004C 8F12 DW 08F12H ; Vertical Displayed + 004E 9615 DW 09615H ; V Blank Start + 0050 B916 DW 0B916H ; V Blank End + 0052 0000 DW nil ; End of CRTC Data for 200/400 Lines + + 0054 MODE_240_Tall: + 0054 MODE_480_Tall: ; CRTC Setup Data for 240/480 Line modes + 0054 0D06 DW 00D06H ; Vertical Total + 0056 3E07 DW 03E07H ; Overflow + 0058 EA10 DW 0EA10H ; V Sync Start + 005A 8C11 DW 08C11H ; V Sync End/Prot Cr0 Cr7 + 005C DF12 DW 0DF12H ; Vertical Displayed + 005E E715 DW 0E715H ; V Blank Start + 0060 0616 DW 00616H ; V Blank End + 0062 0000 DW nil ; End of CRTC Data for 240/480 Lines + + ; Table of Display Mode Tables + + 0064 MODE_TABLE: + 0064 0074 R 0086 R DW o MODE_320x200, o MODE_320x400 + 0068 00E0 R 00F2 R DW o MODE_360x200, o MODE_360x400 + 006C 00BC R 00CE R DW o MODE_320x240, o MODE_320x480 + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 2 - 1 + + + 0070 0098 R 00AA R DW o MODE_360x240, o MODE_360x480 + + ; Table of Display Mode Components + + 0074 MODE_320x200: ; Data for 320 by 200 Pixels + + 0074 63 DB 063h ; 400 scan Lines & 25 Mhz Clock + 0075 04 DB 4 ; Maximum of 4 Pages + 0076 0140 00C8 DW 320, 200 ; Displayed Pixels (X,Y) + 007A 0516 0330 DW 1302, 816 ; Max Possible X and Y Sizes + + 007E 0028 R 0044 R DW o MODE_320_Wide, o MODE_200_Tall + 0082 0020 R 0000 DW o MODE_Double_Line, nil + + 0086 MODE_320x400: ; Data for 320 by 400 Pixels + + 0086 63 DB 063h ; 400 scan Lines & 25 Mhz Clock + 0087 02 DB 2 ; Maximum of 2 Pages + 0088 0140 0190 DW 320, 400 ; Displayed Pixels X,Y + 008C 0288 0330 DW 648, 816 ; Max Possible X and Y Sizes + + 0090 0028 R 0044 R DW o MODE_320_Wide, o MODE_400_Tall + 0094 0018 R 0000 DW o MODE_Single_Line, nil + + 0098 MODE_360x240: ; Data for 360 by 240 Pixels + + 0098 E7 DB 0E7h ; 480 scan Lines & 28 Mhz Clock + 0099 03 DB 3 ; Maximum of 3 Pages + 009A 0168 00F0 DW 360, 240 ; Displayed Pixels X,Y + 009E 0444 02D8 DW 1092, 728 ; Max Possible X and Y Sizes + + 00A2 0036 R 0054 R DW o MODE_360_Wide, o MODE_240_Tall + 00A6 0020 R 0000 DW o MODE_Double_Line , nil + + 00AA MODE_360x480: ; Data for 360 by 480 Pixels + + 00AA E7 DB 0E7h ; 480 scan Lines & 28 Mhz Clock + 00AB 01 DB 1 ; Only 1 Page Possible + 00AC 0168 01E0 DW 360, 480 ; Displayed Pixels X,Y + 00B0 0220 02D8 DW 544, 728 ; Max Possible X and Y Sizes + + 00B4 0036 R 0054 R DW o MODE_360_Wide, o MODE_480_Tall + 00B8 0018 R 0000 DW o MODE_Single_Line , nil + + 00BC MODE_320x240: ; Data for 320 by 240 Pixels + + 00BC E3 DB 0E3h ; 480 scan Lines & 25 Mhz Clock + 00BD 03 DB 3 ; Maximum of 3 Pages + 00BE 0140 00F0 DW 320, 240 ; Displayed Pixels X,Y + 00C2 0440 0332 DW 1088, 818 ; Max Possible X and Y Sizes + + 00C6 0028 R 0054 R DW o MODE_320_Wide, o MODE_240_Tall + 00CA 0020 R 0000 DW o MODE_Double_Line, nil + + 00CE MODE_320x480: ; Data for 320 by 480 Pixels + + 00CE E3 DB 0E3h ; 480 scan Lines & 25 Mhz Clock + 00CF 01 DB 1 ; Only 1 Page Possible + 00D0 0140 01E0 DW 320, 480 ; Displayed Pixels X,Y + 00D4 021C 0332 DW 540, 818 ; Max Possible X and Y Sizes + + 00D8 0028 R 0054 R DW o MODE_320_WIDE, o MODE_480_Tall + 00DC 0018 R 0000 DW o MODE_Single_Line, nil + + 00E0 MODE_360x200: ; Data for 360 by 200 Pixels + + 00E0 67 DB 067h ; 400 scan Lines & 28 Mhz Clock + 00E1 03 DB 3 ; Maximum of 3 Pages + 00E2 0168 00C8 DW 360, 200 ; Displayed Pixels (X,Y) + 00E6 0516 02D8 DW 1302, 728 ; Max Possible X and Y Sizes + + 00EA 0036 R 0044 R DW o MODE_360_Wide, MODE_200_Tall + 00EE 0020 R 0000 DW o MODE_Double_Line, nil + + 00F2 MODE_360x400: ; Data for 360 by 400 Pixels + + 00F2 67 DB 067h ; 400 scan Lines & 28 Mhz Clock + 00F3 01 DB 1 ; Maximum of 1 Pages + 00F4 0168 0190 DW 360, 400 ; Displayed Pixels X,Y + 00F8 0288 0330 DW 648, 816 ; Max Possible X and Y Sizes + + 00FC 0036 R 0044 R DW o MODE_360_Wide, MODE_400_Tall + 0100 0018 R 0000 DW o MODE_Single_Line, nil + + + ; ===== MODE X SETUP ROUTINES ===== + + ;====================================================== + ;SET_VGA_MODEX% (ModeType%, MaxXPos%, MaxYpos%, Pages%) + ;====================================================== + ; + ; Sets Up the specified version of Mode X. Allows for + ; the setup of multiple video pages, and a virtual + ; screen which can be larger than the displayed screen + ; (which can then be scrolled a pixel at a time) + ; + ; ENTRY: ModeType = Desired Screen Resolution (0-7) + ; + ; 0 = 320 x 200, 4 Pages max, 1.2:1 Aspect Ratio + ; 1 = 320 x 400, 2 Pages max, 2.4:1 Aspect Ratio + ; 2 = 360 x 200, 3 Pages max, 1.35:1 Aspect Ratio + ; 3 = 360 x 400, 1 Page max, 2.7:1 Aspect Ratio + ; 4 = 320 x 240, 3 Pages max, 1:1 Aspect Ratio + ; 5 = 320 x 480, 1 Page max, 2:1 Aspect Ratio + ; 6 = 360 x 240, 3 Pages max, 1.125:1 Aspect Ratio + ; 7 = 360 x 480, 1 Page max, 2.25:1 Aspect Ratio + ; + ; MaxXpos = The Desired Virtual Screen Width + ; MaxYpos = The Desired Virtual Screen Height + ; Pages = The Desired # of Video Pages + ; + ; EXIT: AX = Success Flag: 0 = Failure / -1= Success + ; + + 0016 SVM_STACK STRUC + 0000 0000 SVM_Table DW ? ; Offset of Mode Info Table + 0002 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 000A 00000000 DD ? ; Caller + 000E 0000 SVM_Pages DW ? ; # of Screen Pages desired + 0010 0000 SVM_Ysize DW ? ; Vertical Screen Size Desired + 0012 0000 SVM_Xsize DW ? ; Horizontal Screen Size Desired + 0014 0000 SVM_Mode DW ? ; Display Resolution Desired + SVM_STACK ENDS + + PUBLIC SET_VGA_MODEX + + 0104 SET_VGA_MODEX PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0104 55 1 PUSH BP ; Save R1 + 0105 1E 2 PUSH DS ; Save R1 + 0106 56 3 PUSH SI ; Save R1 + 0107 57 4 PUSH DI ; Save R1 + 0108 83 EC 02 SUB SP, 2 ; Allocate workspace + 010B 8B EC MOV BP, SP ; Set up Stack Frame + + ; Check Legality of Mode Request.... + + 010D 8B 5E 14 MOV BX, [BP].SVM_Mode ; Get Requested Mode # + 0110 83 FB 08 CMP BX, NUM_MODES ; Is it 0..7? + 0113 73 47 JAE @SVM_BadModeSetup ; If Not, Error out + + 0115 D1 E3 SHL BX, 1 ; Scale BX + 0117 2E: 8B B7 0064 R MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + 011C 89 76 00 MOV [BP].SVM_Table, SI ; Save ptr for later use + + ; Check # of Requested Display Pages + + 011F 8B 4E 0E MOV CX, [BP].SVM_Pages ; Get # of Requested Pages + CLR CH ; Set Hi Word = 0! + 0122 32 ED 1 XOR CH, CH ; Set Register = 0 + 0124 2E: 3A 4C 01 CMP CL, CS:[SI].M_Pages ; Check # Pages for mode + 0128 77 32 JA @SVM_BadModeSetup ; Report Error if too Many Pages + 012A E3 30 JCXZ @SVM_BadModeSetup ; Report Error if 0 Pages + + ; Check Validity of X Size + + 012C 83 66 12 F8 AND [BP].SVM_XSize, 0FFF8h ; X size Mod 8 Must = 0 + + 0130 8B 46 12 MOV AX, [BP].SVM_XSize ; Get Logical Screen Width + 0133 2E: 3B 44 02 CMP AX, CS:[SI].M_XSize ; Check against Displayed X + 0137 72 23 JB @SVM_BadModeSetup ; Report Error if too small + 0139 2E: 3B 44 06 CMP AX, CS:[SI].M_XMax ; Check against Max X + 013D 77 1D JA @SVM_BadModeSetup ; Report Error if too big + + ; Check Validity of Y Size + + 013F 8B 5E 10 MOV BX, [BP].SVM_YSize ; Get Logical Screen Height + 0142 2E: 3B 5C 04 CMP BX, CS:[SI].M_YSize ; Check against Displayed Y + 0146 72 14 JB @SVM_BadModeSetup ; Report Error if too small + 0148 2E: 3B 5C 08 CMP BX, CS:[SI].M_YMax ; Check against Max Y + 014C 77 0E JA @SVM_BadModeSetup ; Report Error if too big + + ; Enough memory to Fit it all? + + 014E C1 E8 02 SHR AX, 2 ; # of Bytes:Line = XSize/4 + 0151 F7 E1 MUL CX ; AX = Bytes/Line * Pages + 0153 F7 E3 MUL BX ; DX:AX = Total VGA mem needed + 0155 71 0A JNO @SVM_Continue ; Exit if Total Size > 256K + + 0157 4A DEC DX ; Was it Exactly 256K??? + 0158 0B D0 OR DX, AX ; (DX = 1, AX = 0000) + 015A 74 05 JZ @SVM_Continue ; if so, it's valid... + + 015C @SVM_BadModeSetup: + + CLR AX ; Return Value = False + 015C 33 C0 1 XOR AX, AX ; Set Register = 0 + 015E E9 00E6 JMP @SVM_Exit ; Normal Exit + + 0161 @SVM_Continue: + + 0161 B8 0013 MOV AX, 13H ; Start with Mode 13H + 0164 CD 10 INT 10H ; Let BIOS Set Mode + + OUT_16 SC_INDEX, CHAIN4_OFF ; Disable Chain 4 Mode + 0166 BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0169 B8 0604 1 MOV AX, CHAIN4_OFF ; then Get Data Value + 016C EF 1 OUT DX, AX ; Set I/O Register(s) + OUT_16 SC_INDEX, ASYNC_RESET ; (A)synchronous Reset + 016D BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0170 B8 0100 1 MOV AX, ASYNC_RESET ; then Get Data Value + 0173 EF 1 OUT DX, AX ; Set I/O Register(s) + OUT_8 MISC_OUTPUT, CS:[SI].M_MiscR ; Set New Timing/Size + 0174 BA 03C2 1 MOV DX, MISC_OUTPUT ; then Select Register + 0177 2E: 8A 04 1 MOV AL, CS:[SI].M_MiscR ; then Get Data Value + 017A EE 1 OUT DX, AL ; Set I/O Register + OUT_16 SC_INDEX, SEQU_RESTART ; Restart Sequencer ... + 017B BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 017E B8 0300 1 MOV AX, SEQU_RESTART ; then Get Data Value + 0181 EF 1 OUT DX, AX ; Set I/O Register(s) + + OUT_8 CRTC_INDEX, 11H ; Select Vert Retrace End Register + 0182 BA 03D4 1 MOV DX, CRTC_INDEX ; then Select Register + 0185 B0 11 1 MOV AL, 11H ; then Get Data Value + 0187 EE 1 OUT DX, AL ; Set I/O Register + 0188 42 INC DX ; Point to Data + 0189 EC IN AL, DX ; Get Value, Bit 7 = Protect + 018A 24 7F AND AL, 7FH ; Mask out Write Protect + 018C EE OUT DX, AL ; And send it back + + 018D BA 03D4 MOV DX, CRTC_INDEX ; Vga Crtc Registers + 0190 83 C6 0A ADD SI, M_CRTC ; SI -> CRTC Parameter Data + + ; Load Tables of CRTC Parameters from List of Tables + + 0193 @SVM_Setup_Table: + + 0193 2E: 8B 3C MOV DI, CS:[SI] ; Get Pointer to CRTC Data Tbl + 0196 83 C6 02 ADD SI, 2 ; Point to next Ptr Entry + 0199 0B FF OR DI, DI ; A nil Ptr means that we have + 019B 74 0D JZ @SVM_Set_Data ; finished CRTC programming + + 019D @SVM_Setup_CRTC: + 019D 2E: 8B 05 MOV AX, CS:[DI] ; Get CRTC Data from Table + 01A0 83 C7 02 ADD DI, 2 ; Advance Pointer + 01A3 0B C0 OR AX, AX ; At End of Data Table? + 01A5 74 EC JZ @SVM_Setup_Table ; If so, Exit & get next Table + + 01A7 EF OUT DX, AX ; Reprogram VGA CRTC reg + 01A8 EB F3 JMP s @SVM_Setup_CRTC ; Process Next Table Entry + + ; Initialize Page & Scroll info, DI = 0 + + 01AA @SVM_Set_Data: + 01AA 89 3E 0010 R MOV DISPLAY_PAGE, DI ; Display Page = 0 + 01AE 89 3E 0012 R MOV ACTIVE_PAGE, DI ; Active Page = 0 + 01B2 89 3E 0014 R MOV CURRENT_PAGE, DI ; Current Page (Offset) = 0 + 01B6 89 3E 0018 R MOV CURRENT_XOFFSET, DI ; Horz Scroll Index = 0 + 01BA 89 3E 001A R MOV CURRENT_YOFFSET, DI ; Vert Scroll Index = 0 + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 3 - 1 + + + 01BE 89 3E 001C R MOV CURRENT_MOFFSET, DI ; Memory Scroll Index = 0 + + 01C2 B8 A000 MOV AX, VGA_SEGMENT ; Segment for VGA memory + 01C5 A3 0016 R MOV CURRENT_SEGMENT, AX ; Save for Future LES's + + ; Set Logical Screen Width, X Scroll and Our Data + + 01C8 8B 76 00 MOV SI, [BP].SVM_Table ; Get Saved Ptr to Mode Info + 01CB 8B 46 12 MOV AX, [BP].SVM_Xsize ; Get Display Width + + 01CE 8B C8 MOV CX, AX ; CX = Logical Width + 01D0 2E: 2B 4C 02 SUB CX, CS:[SI].M_XSize ; CX = Max X Scroll Value + 01D4 89 0E 001E R MOV MAX_XOFFSET, CX ; Set Maximum X Scroll + + 01D8 C1 E8 02 SHR AX, 2 ; Bytes = Pixels / 4 + 01DB A3 0000 R MOV SCREEN_WIDTH, AX ; Save Width in Pixels + + 01DE D1 E8 SHR AX, 1 ; Offset Value = Bytes / 2 + 01E0 B4 13 MOV AH, 13h ; CRTC Offset Register Index + 01E2 86 C4 XCHG AL, AH ; Switch format for OUT + 01E4 EF OUT DX, AX ; Set VGA CRTC Offset Reg + + ; Setup Data table, Y Scroll, Misc for Other Routines + + 01E5 8B 46 10 MOV AX, [BP].SVM_Ysize ; Get Logical Screen Height + + 01E8 8B C8 MOV CX, AX ; CX = Logical Height + 01EA 2E: 2B 5C 04 SUB BX, CS:[SI].M_YSize ; CX = Max Y Scroll Value + 01EE 89 0E 0020 R MOV MAX_YOFFSET, CX ; Set Maximum Y Scroll + + 01F2 A3 0002 R MOV SCREEN_HEIGHT, AX ; Save Height in Pixels + 01F5 F7 26 0000 R MUL SCREEN_WIDTH ; AX = Page Size in Bytes, + 01F9 A3 000E R MOV PAGE_SIZE, AX ; Save Page Size + + 01FC 8B 4E 0E MOV CX, [BP].SVM_Pages ; Get # of Pages + 01FF 89 0E 0004 R MOV LAST_PAGE, CX ; Save # of Pages + + CLR BX ; Page # = 0 + 0203 33 DB 1 XOR BX, BX ; Set Register = 0 + 0205 8B D3 MOV DX, BX ; Page 0 Offset = 0 + + 0207 @SVM_Set_Pages: + + 0207 89 97 0006 R MOV PAGE_ADDR[BX], DX ; Set Page #(BX) Offset + 020B 83 C3 02 ADD BX, 2 ; Page#++ + 020E 03 D0 ADD DX, AX ; Compute Addr of Next Page + LOOPx CX, @SVM_Set_Pages ; Loop until all Pages Set + 0210 49 1 DEC CX ; Counter-- + 0211 75 F4 1 JNZ @SVM_Set_Pages ; Jump if not 0 + + ; Clear VGA Memory + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + 0213 BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0216 B8 0F02 1 MOV AX, ALL_PLANES_ON ; then Get Data Value + 0219 EF 1 OUT DX, AX ; Set I/O Register(s) + 021A C4 3E 0014 R LES DI, d CURRENT_PAGE ; -> Start of VGA memory + + CLR AX ; AX = 0 + 021E 33 C0 1 XOR AX, AX ; Set Register = 0 + 0220 FC CLD ; Block Xfer Forwards + 0221 B9 8000 MOV CX, 8000H ; 32K * 4 * 2 = 256K + 0224 F3/ AB REP STOSW ; Clear dat memory! + + ; Setup Font Pointers + + 0226 B7 03 MOV BH, ROM_8x8_Lo ; Ask for 8x8 Font, 0-127 + 0228 B8 1130 MOV AX, GET_CHAR_PTR ; Service to Get Pointer + 022B CD 10 INT 10h ; Call VGA BIOS + + 022D 89 2E 0022 R MOV CHARSET_LOW, BP ; Save Char Set Offset + 0231 8C 06 0024 R MOV CHARSET_LOW+2, ES ; Save Char Set Segment + + 0235 B7 04 MOV BH, ROM_8x8_Hi ; Ask for 8x8 Font, 128-255 + 0237 B8 1130 MOV AX, GET_CHAR_PTR ; Service to Get Pointer + 023A CD 10 INT 10h ; Call VGA BIOS + + 023C 89 2E 0026 R MOV CHARSET_HI, BP ; Save Char Set Offset + 0240 8C 06 0028 R MOV CHARSET_HI+2, ES ; Save Char Set Segment + + 0244 B8 FFFF MOV AX, True ; Return Success Code + + 0247 @SVM_EXIT: + 0247 83 C4 02 ADD SP, 2 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 024A 5F 1 POP DI ; Restore R1 + 024B 5E 2 POP SI ; Restore R1 + 024C 1F 3 POP DS ; Restore R1 + 024D 5D 4 POP BP ; Restore R1 + 024E CA 0008 RET 8 ; Exit & Clean Up Stack + + 0251 SET_VGA_MODEX ENDP + + + ;================== + ;SET_MODEX% (Mode%) + ;================== + ; + ; Quickie Mode Set - Sets Up Mode X to Default Configuration + ; + ; ENTRY: ModeType = Desired Screen Resolution (0-7) + ; (See SET_VGA_MODEX for list) + ; + ; EXIT: AX = Success Flag: 0 = Failure / -1= Success + ; + + 000A SM_STACK STRUC + 0000 0000 0000 DW ?,? ; BP, SI + 0004 00000000 DD ? ; Caller + 0008 0000 SM_Mode DW ? ; Desired Screen Resolution + SM_STACK ENDS + + PUBLIC SET_MODEX + + 0251 SET_MODEX PROC FAR + + PUSHx BP, SI ; Preserve Important registers + 0251 55 1 PUSH BP ; Save R1 + 0252 56 2 PUSH SI ; Save R1 + 0253 8B EC MOV BP, SP ; Set up Stack Frame + + CLR AX ; Assume Failure + 0255 33 C0 1 XOR AX, AX ; Set Register = 0 + 0257 8B 5E 08 MOV BX, [BP].SM_Mode ; Get Desired Mode # + 025A 83 FB 08 CMP BX, NUM_MODES ; Is it a Valid Mode #? + 025D 73 1C JAE @SMX_Exit ; If Not, don't Bother + + 025F 53 PUSH BX ; Push Mode Parameter + + 0260 D1 E3 SHL BX, 1 ; Scale BX to word Index + 0262 2E: 8B B7 0064 R MOV SI, w MODE_TABLE[BX] ; CS:SI -> Mode Info + + 0267 2E: FF 74 02 PUSH CS:[SI].M_XSize ; Push Default X Size + 026B 2E: FF 74 04 PUSH CS:[SI].M_Ysize ; Push Default Y size + 026F 2E: 8A 44 01 MOV AL, CS:[SI].M_Pages ; Get Default # of Pages + CLR AH ; Hi Byte = 0 + 0273 32 E4 1 XOR AH, AH ; Set Register = 0 + 0275 50 PUSH AX ; Push # Pages + + 0276 9A ---- 0104 R CALL f SET_VGA_MODEX ; Set up Mode X! + + 027B @SMX_Exit: + POPx SI, BP ; Restore Registers + 027B 5E 1 POP SI ; Restore R1 + 027C 5D 2 POP BP ; Restore R1 + 027D CA 0002 RET 2 ; Exit & Clean Up Stack + + 0280 SET_MODEX ENDP + + + ; ===== BASIC GRAPHICS PRIMITIVES ===== + + ;============================ + ;CLEAR_VGA_SCREEN (ColorNum%) + ;============================ + ; + ; Clears the active display page + ; + ; ENTRY: ColorNum = Color Value to fill the page with + ; + ; EXIT: No meaningful values returned + ; + + 000A CVS_STACK STRUC + 0000 0000 0000 DW ?,? ; DI, BP + 0004 00000000 DD ? ; Caller + 0008 00 00 CVS_COLOR DB ?,? ; Color to Set Screen to + CVS_STACK ENDS + + PUBLIC CLEAR_VGA_SCREEN + + 0280 CLEAR_VGA_SCREEN PROC FAR + + PUSHx BP, DI ; Preserve Important Registers + 0280 55 1 PUSH BP ; Save R1 + 0281 57 2 PUSH DI ; Save R1 + 0282 8B EC MOV BP, SP ; Set up Stack Frame + + OUT_16 SC_INDEX, ALL_PLANES_ON ; Select All Planes + 0284 BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0287 B8 0F02 1 MOV AX, ALL_PLANES_ON ; then Get Data Value + 028A EF 1 OUT DX, AX ; Set I/O Register(s) + 028B C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 028F 8A 46 08 MOV AL, [BP].CVS_COLOR ; Get Color + 0292 8A E0 MOV AH, AL ; Copy for Word Write + 0294 FC CLD ; Block fill Forwards + + 0295 8B 0E 000E R MOV CX, PAGE_SIZE ; Get Size of Page + 0299 D1 E9 SHR CX, 1 ; Divide by 2 for Words + 029B F3/ AB REP STOSW ; Block Fill VGA memory + + POPx DI, BP ; Restore Saved Registers + 029D 5F 1 POP DI ; Restore R1 + 029E 5D 2 POP BP ; Restore R1 + 029F CA 0002 RET 2 ; Exit & Clean Up Stack + + 02A2 CLEAR_VGA_SCREEN ENDP + + + ;=================================== + ;SET_POINT (Xpos%, Ypos%, ColorNum%) + ;=================================== + ; + ; Plots a single Pixel on the active display page + ; + ; ENTRY: Xpos = X position to plot pixel at + ; Ypos = Y position to plot pixel at + ; ColorNum = Color to plot pixel with + ; + ; EXIT: No meaningful values returned + ; + + 000E SP_STACK STRUC + 0000 0000 0000 DW ?,? ; BP, DI + 0004 00000000 DD ? ; Caller + 0008 00 00 SETP_Color DB ?,? ; Color of Point to Plot + 000A 0000 SETP_Ypos DW ? ; Y pos of Point to Plot + 000C 0000 SETP_Xpos DW ? ; X pos of Point to Plot + SP_STACK ENDS + + PUBLIC SET_POINT + + 02A2 SET_POINT PROC FAR + + PUSHx BP, DI ; Preserve Registers + 02A2 55 1 PUSH BP ; Save R1 + 02A3 57 2 PUSH DI ; Save R1 + 02A4 8B EC MOV BP, SP ; Set up Stack Frame + + 02A6 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 02AA 8B 46 0A MOV AX, [BP].SETP_Ypos ; Get Line # of Pixel + 02AD F7 26 0000 R MUL SCREEN_WIDTH ; Get Offset to Start of Line + + 02B1 8B 5E 0C MOV BX, [BP].SETP_Xpos ; Get Xpos + 02B4 8B CB MOV CX, BX ; Copy to extract Plane # from + 02B6 C1 EB 02 SHR BX, 2 ; X offset (Bytes) = Xpos/4 + 02B9 03 D8 ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + 02BB B8 0102 MOV AX, MAP_MASK_PLANE1 ; Map Mask & Plane Select Register + 02BE 80 E1 03 AND CL, PLANE_BITS ; Get Plane Bits + 02C1 D2 E4 SHL AH, CL ; Get Plane Select Value + OUT_16 SC_Index, AX ; Select Plane + 02C3 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 02C6 EF 1 OUT DX, AX ; Set I/O Register(s) + + 02C7 8A 46 08 MOV AL,[BP].SETP_Color ; Get Pixel Color + 02CA 26: 88 01 MOV ES:[DI+BX], AL ; Draw Pixel + + POPx DI, BP ; Restore Saved Registers + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 4 - 1 + + + 02CD 5F 1 POP DI ; Restore R1 + 02CE 5D 2 POP BP ; Restore R1 + 02CF CA 0006 RET 6 ; Exit and Clean up Stack + + 02D2 SET_POINT ENDP + + + ;========================== + ;READ_POINT% (Xpos%, Ypos%) + ;========================== + ; + ; Read the color of a pixel from the Active Display Page + ; + ; ENTRY: Xpos = X position of pixel to read + ; Ypos = Y position of pixel to read + ; + ; EXIT: AX = Color of Pixel at (Xpos, Ypos) + ; + + 000C RP_STACK STRUC + 0000 0000 0000 DW ?,? ; BP, DI + 0004 00000000 DD ? ; Caller + 0008 0000 RP_Ypos DW ? ; Y pos of Point to Read + 000A 0000 RP_Xpos DW ? ; X pos of Point to Read + RP_STACK ENDS + + PUBLIC READ_POINT + + 02D2 READ_POINT PROC FAR + + PUSHx BP, DI ; Preserve Registers + 02D2 55 1 PUSH BP ; Save R1 + 02D3 57 2 PUSH DI ; Save R1 + 02D4 8B EC MOV BP, SP ; Set up Stack Frame + + 02D6 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 02DA 8B 46 08 MOV AX, [BP].RP_Ypos ; Get Line # of Pixel + 02DD F7 26 0000 R MUL SCREEN_WIDTH ; Get Offset to Start of Line + + 02E1 8B 5E 0A MOV BX, [BP].RP_Xpos ; Get Xpos + 02E4 8B CB MOV CX, BX + 02E6 C1 EB 02 SHR BX, 2 ; X offset (Bytes) = Xpos/4 + 02E9 03 D8 ADD BX, AX ; Offset = Width*Ypos + Xpos/4 + + 02EB B0 04 MOV AL, READ_MAP ; GC Read Mask Register + 02ED 8A E1 MOV AH, CL ; Get Xpos + 02EF 80 E4 03 AND AH, PLANE_BITS ; & mask out Plane # + OUT_16 GC_INDEX, AX ; Select Plane to read in + 02F2 BA 03CE 1 MOV DX, GC_INDEX ; then Select Register + 02F5 EF 1 OUT DX, AX ; Set I/O Register(s) + + CLR AH ; Clear Return Value Hi byte + 02F6 32 E4 1 XOR AH, AH ; Set Register = 0 + 02F8 26: 8A 01 MOV AL, ES:[DI+BX] ; Get Color of Pixel + + POPx DI, BP ; Restore Saved Registers + 02FB 5F 1 POP DI ; Restore R1 + 02FC 5D 2 POP BP ; Restore R1 + 02FD CA 0004 RET 4 ; Exit and Clean up Stack + + 0300 READ_POINT ENDP + + + ;====================================================== + ;FILL_BLOCK (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) + ;====================================================== + ; + ; Fills a rectangular block on the active display Page + ; + ; ENTRY: Xpos1 = Left X position of area to fill + ; Ypos1 = Top Y position of area to fill + ; Xpos2 = Right X position of area to fill + ; Ypos2 = Bottom Y position of area to fill + ; ColorNum = Color to fill area with + ; + ; EXIT: No meaningful values returned + ; + + 0016 FB_STACK STRUC + 0000 0000 0000 0000 DW ?x4 ; DS, DI, SI, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 00 00 FB_Color DB ?,? ; Fill Color + 000E 0000 FB_Ypos2 DW ? ; Y pos of Lower Right Pixel + 0010 0000 FB_Xpos2 DW ? ; X pos of Lower Right Pixel + 0012 0000 FB_Ypos1 DW ? ; Y pos of Upper Left Pixel + 0014 0000 FB_Xpos1 DW ? ; X pos of Upper Left Pixel + FB_STACK ENDS + + PUBLIC FILL_BLOCK + + 0300 FILL_BLOCK PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0300 55 1 PUSH BP ; Save R1 + 0301 1E 2 PUSH DS ; Save R1 + 0302 56 3 PUSH SI ; Save R1 + 0303 57 4 PUSH DI ; Save R1 + 0304 8B EC MOV BP, SP ; Set up Stack Frame + + 0306 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + 030A FC CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + 030B BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 030E B0 02 1 MOV AL, MAP_MASK ; then Get Data Value + 0310 EE 1 OUT DX, AL ; Set I/O Register + + ; Validate Pixel Coordinates + ; If necessary, Swap so X1 <= X2, Y1 <= Y2 + + 0311 8B 46 12 MOV AX, [BP].FB_Ypos1 ; AX = Y1 is Y1< Y2? + 0314 8B 5E 0E MOV BX, [BP].FB_Ypos2 ; BX = Y2 + 0317 3B C3 CMP AX, BX + 0319 7E 04 JLE @FB_NOSWAP1 + + 031B 89 5E 12 MOV [BP].FB_Ypos1, BX ; Swap Y1 and Y2 and save Y1 + 031E 93 XCHG AX, BX ; on stack for future use + + 031F @FB_NOSWAP1: + 031F 2B D8 SUB BX, AX ; Get Y width + 0321 43 INC BX ; Add 1 to avoid 0 value + 0322 89 5E 0E MOV [BP].FB_Ypos2, BX ; Save in Ypos2 + + 0325 F7 26 0000 R MUL SCREEN_WIDTH ; Mul Y1 by Bytes per Line + 0329 03 F8 ADD DI, AX ; DI = Start of Line Y1 + + 032B 8B 46 14 MOV AX, [BP].FB_Xpos1 ; Check X1 <= X2 + 032E 8B 5E 10 MOV BX, [BP].FB_Xpos2 ; + 0331 3B C3 CMP AX, BX + 0333 7E 04 JLE @FB_NOSWAP2 ; Skip Ahead if Ok + + 0335 89 46 10 MOV [BP].FB_Xpos2, AX ; Swap X1 AND X2 and save X2 + 0338 93 XCHG AX, BX ; on stack for future use + + ; All our Input Values are in order, Now determine + ; How many full "bands" 4 pixels wide (aligned) there + ; are, and if there are partial bands (<4 pixels) on + ; the left and right edges. + + 0339 @FB_NOSWAP2: + 0339 8B D0 MOV DX, AX ; DX = X1 (Pixel Position) + 033B C1 EA 02 SHR DX, 2 ; DX/4 = Bytes into Line + 033E 03 FA ADD DI, DX ; DI = Addr of Upper-Left Corner + + 0340 8B CB MOV CX, BX ; CX = X2 (Pixel Position) + 0342 C1 E9 02 SHR CX, 2 ; CX/4 = Bytes into Line + + 0345 3B D1 CMP DX, CX ; Start and end in same band? + 0347 75 03 JNE @FB_NORMAL ; if not, check for l & r edges + 0349 E9 0086 JMP @FB_ONE_BAND_ONLY ; if so, then special processing + + 034C @FB_NORMAL: + 034C 2B CA SUB CX, DX ; CX = # bands -1 + 034E 8B F0 MOV SI, AX ; SI = PLANE#(X1) + 0350 83 E6 03 AND SI, PLANE_BITS ; if Left edge is aligned then + 0353 74 27 JZ @FB_L_PLANE_FLUSH ; no special processing.. + + ; Draw "Left Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Left_Clip_Mask[SI] ; Set Left Edge Plane Mask + 0355 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0358 2E: 8A 84 0000 R 1 MOV AL, Left_Clip_Mask[SI] ; then Get Data Value + 035D EE 1 OUT DX, AL ; Set I/O Register + + 035E 8B F7 MOV SI, DI ; SI = Copy of Start Addr (UL) + + 0360 8B 56 0E MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + 0363 8A 46 0C MOV AL, [BP].FB_Color ; Get Fill Color + 0366 8B 1E 0000 R MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + + 036A @FB_LEFT_LOOP: + 036A 26: 88 04 MOV ES:[SI], AL ; Fill in Left Edge Pixels + 036D 03 F3 ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_LEFT_CONT ; Exit loop if all Lines Drawn + 036F 4A 1 DEC DX ; Counter-- + 0370 74 08 1 JZ @FB_LEFT_CONT ; Jump if 0 + + 0372 26: 88 04 MOV ES:[SI], AL ; Fill in Left Edge Pixels + 0375 03 F3 ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_LEFT_LOOP ; loop until left strip is drawn + 0377 4A 1 DEC DX ; Counter-- + 0378 75 F0 1 JNZ @FB_LEFT_LOOP ; Jump if not 0 + + 037A @FB_LEFT_CONT: + + 037A 47 INC DI ; Point to Middle (or Right) Block + 037B 49 DEC CX ; Reset CX instead of JMP @FB_RIGHT + + 037C @FB_L_PLANE_FLUSH: + 037C 41 INC CX ; Add in Left band to middle block + + ; DI = Addr of 1st middle Pixel (band) to fill + ; CX = # of Bands to fill -1 + + 037D @FB_RIGHT: + 037D 8B 76 10 MOV SI, [BP].FB_Xpos2 ; Get Xpos2 + 0380 83 E6 03 AND SI, PLANE_BITS ; Get Plane values + 0383 83 FE 03 CMP SI, 0003 ; Plane = 3? + 0386 74 2B JE @FB_R_EDGE_FLUSH ; Hey, add to middle + + ; Draw "Right Edge" vertical strip of 1-3 pixels... + + OUT_8 SC_Data, Right_Clip_Mask[SI] ; Right Edge Plane Mask + 0388 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 038B 2E: 8A 84 0004 R 1 MOV AL, Right_Clip_Mask[SI] ; then Get Data Value + 0390 EE 1 OUT DX, AL ; Set I/O Register + + 0391 8B F7 MOV SI, DI ; Get Addr of Left Edge + 0393 03 F1 ADD SI, CX ; Add Width-1 (Bands) + 0395 4E DEC SI ; To point to top of Right Edge + + 0396 8B 56 0E MOV DX, [BP].FB_Ypos2 ; Get # of Lines to draw + 0399 8A 46 0C MOV AL, [BP].FB_Color ; Get Fill Color + 039C 8B 1E 0000 R MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + + 03A0 @FB_RIGHT_LOOP: + 03A0 26: 88 04 MOV ES:[SI], AL ; Fill in Right Edge Pixels + 03A3 03 F3 ADD SI, BX ; Point to Next Line (Below) + LOOPjz DX, @FB_RIGHT_CONT ; Exit loop if all Lines Drawn + 03A5 4A 1 DEC DX ; Counter-- + 03A6 74 08 1 JZ @FB_RIGHT_CONT ; Jump if 0 + + 03A8 26: 88 04 MOV ES:[SI], AL ; Fill in Right Edge Pixels + 03AB 03 F3 ADD SI, BX ; Point to Next Line (Below) + LOOPx DX, @FB_RIGHT_LOOP ; loop until left strip is drawn + 03AD 4A 1 DEC DX ; Counter-- + 03AE 75 F0 1 JNZ @FB_RIGHT_LOOP ; Jump if not 0 + + 03B0 @FB_RIGHT_CONT: + + 03B0 49 DEC CX ; Minus 1 for Middle bands + 03B1 74 51 JZ @FB_EXIT ; Uh.. no Middle bands... + + 03B3 @FB_R_EDGE_FLUSH: + + ; DI = Addr of Upper Left block to fill + ; CX = # of Bands to fill in (width) + + OUT_8 SC_Data, ALL_PLANES ; Write to All Planes + 03B3 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 03B6 B0 0F 1 MOV AL, ALL_PLANES ; then Get Data Value + 03B8 EE 1 OUT DX, AL ; Set I/O Register + + 03B9 8B 16 0000 R MOV DX, SCREEN_WIDTH ; DX = DI Increment + 03BD 2B D1 SUB DX, CX ; = Screen_Width-# Planes Filled + + 03BF 8B D9 MOV BX, CX ; BX = Quick Refill for CX + 03C1 8B 76 0E MOV SI, [BP].FB_Ypos2 ; SI = # of Line to Fill + 03C4 8A 46 0C MOV AL, [BP].FB_Color ; Get Fill Color + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 5 - 1 + + + + 03C7 @FB_MIDDLE_LOOP: + 03C7 F3/ AA REP STOSB ; Fill in entire line + + 03C9 8B CB MOV CX, BX ; Recharge CX (Line Width) + 03CB 03 FA ADD DI, DX ; Point to start of Next Line + LOOPx SI, @FB_MIDDLE_LOOP ; Loop until all lines drawn + 03CD 4E 1 DEC SI ; Counter-- + 03CE 75 F7 1 JNZ @FB_MIDDLE_LOOP ; Jump if not 0 + + 03D0 EB 32 JMP s @FB_EXIT ; Outa here + + 03D2 @FB_ONE_BAND_ONLY: + 03D2 8B F0 MOV SI, AX ; Get Left Clip Mask, Save X1 + 03D4 83 E6 03 AND SI, PLANE_BITS ; Mask out Row # + 03D7 2E: 8A 84 0000 R MOV AL, Left_Clip_Mask[SI] ; Get Left Edge Mask + 03DC 8B F3 MOV SI, BX ; Get Right Clip Mask, Save X2 + 03DE 83 E6 03 AND SI, PLANE_BITS ; Mask out Row # + 03E1 2E: 22 84 0004 R AND AL, Right_Clip_Mask[SI] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + 03E6 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 03E9 EE 1 OUT DX, AL ; Set I/O Register + + 03EA 8B 4E 0E MOV CX, [BP].FB_Ypos2 ; Get # of Lines to draw + 03ED 8A 46 0C MOV AL, [BP].FB_Color ; Get Fill Color + 03F0 8B 1E 0000 R MOV BX, SCREEN_WIDTH ; Get Vertical increment Value + + 03F4 @FB_ONE_LOOP: + 03F4 26: 88 05 MOV ES:[DI], AL ; Fill in Pixels + 03F7 03 FB ADD DI, BX ; Point to Next Line (Below) + LOOPjz CX, @FB_EXIT ; Exit loop if all Lines Drawn + 03F9 49 1 DEC CX ; Counter-- + 03FA 74 08 1 JZ @FB_EXIT ; Jump if 0 + + 03FC 26: 88 05 MOV ES:[DI], AL ; Fill in Pixels + 03FF 03 FB ADD DI, BX ; Point to Next Line (Below) + LOOPx CX, @FB_ONE_LOOP ; loop until left strip is drawn + 0401 49 1 DEC CX ; Counter-- + 0402 75 F0 1 JNZ @FB_ONE_LOOP ; Jump if not 0 + + 0404 @FB_EXIT: + POPx DI, SI, DS, BP ; Restore Saved Registers + 0404 5F 1 POP DI ; Restore R1 + 0405 5E 2 POP SI ; Restore R1 + 0406 1F 3 POP DS ; Restore R1 + 0407 5D 4 POP BP ; Restore R1 + 0408 CA 000A RET 10 ; Exit and Clean up Stack + + 040B FILL_BLOCK ENDP + + + ;===================================================== + ;DRAW_LINE (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%) + ;===================================================== + ; + ; Draws a Line on the active display page + ; + ; ENTRY: Xpos1 = X position of first point on line + ; Ypos1 = Y position of first point on line + ; Xpos2 = X position of last point on line + ; Ypos2 = Y position of last point on line + ; ColorNum = Color to draw line with + ; + ; EXIT: No meaningful values returned + ; + + 0014 DL_STACK STRUC + 0000 0000 0000 0000 DW ?x3 ; DI, SI, BP + 0006 00000000 DD ? ; Caller + 000A 00 00 DL_ColorF DB ?,? ; Line Draw Color + 000C 0000 DL_Ypos2 DW ? ; Y pos of last point + 000E 0000 DL_Xpos2 DW ? ; X pos of last point + 0010 0000 DL_Ypos1 DW ? ; Y pos of first point + 0012 0000 DL_Xpos1 DW ? ; X pos of first point + DL_STACK ENDS + + PUBLIC DRAW_LINE + + 040B DRAW_LINE PROC FAR + + PUSHx BP, SI, DI ; Preserve Important Registers + 040B 55 1 PUSH BP ; Save R1 + 040C 56 2 PUSH SI ; Save R1 + 040D 57 3 PUSH DI ; Save R1 + 040E 8B EC MOV BP, SP ; Set up Stack Frame + 0410 FC CLD ; Direction Flag = Forward + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + 0411 BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0414 B0 02 1 MOV AL, MAP_MASK ; then Get Data Value + 0416 EE 1 OUT DX, AL ; Set I/O Register + 0417 8A 6E 0A MOV CH, [BP].DL_ColorF ; Save Line Color in CH + + ; Check Line Type + + 041A 8B 76 12 MOV SI, [BP].DL_Xpos1 ; AX = X1 is X1< X2? + 041D 8B 7E 0E MOV DI, [BP].DL_Xpos2 ; DX = X2 + 0420 3B F7 CMP SI, DI ; Is X1 < X2 + 0422 74 5D JE @DL_VLINE ; If X1=X2, Draw Vertical Line + 0424 7C 02 JL @DL_NOSWAP1 ; If X1 < X2, don't swap + + 0426 87 F7 XCHG SI, DI ; X2 IS > X1, SO SWAP THEM + + 0428 @DL_NOSWAP1: + + ; SI = X1, DI = X2 + + 0428 8B 46 10 MOV AX, [BP].DL_Ypos1 ; AX = Y1 is Y1 <> Y2? + 042B 3B 46 0C CMP AX, [BP].DL_Ypos2 ; Y1 = Y2? + 042E 74 03 JE @DL_HORZ ; If so, Draw a Horizontal Line + + 0430 E9 0094 JMP @DL_BREZHAM ; Diagonal line... go do it... + + ; This Code draws a Horizontal Line in Mode X where: + ; SI = X1, DI = X2, and AX = Y1/Y2 + + 0433 @DL_HORZ: + + 0433 F7 26 0000 R MUL SCREEN_WIDTH ; Offset = Ypos * Screen_Width + 0437 8B D0 MOV DX, AX ; CX = Line offset into Page + + 0439 8B C6 MOV AX, SI ; Get Left edge, Save X1 + 043B 83 E6 03 AND SI, PLANE_BITS ; Mask out Row # + 043E 2E: 8A 9C 0000 R MOV BL, Left_Clip_Mask[SI] ; Get Left Edge Mask + 0443 8B CF MOV CX, DI ; Get Right edge, Save X2 + 0445 83 E7 03 AND DI, PLANE_BITS ; Mask out Row # + 0448 2E: 8A BD 0004 R MOV BH, Right_Clip_Mask[DI] ; Get Right Edge Mask byte + + 044D C1 E8 02 SHR AX, 2 ; Get X1 Byte # (=X1/4) + 0450 C1 E9 02 SHR CX, 2 ; Get X2 Byte # (=X2/4) + + 0453 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + 0457 03 FA ADD DI, DX ; Point to Start of Line + 0459 03 F8 ADD DI, AX ; Point to Pixel X1 + + 045B 2B C8 SUB CX, AX ; CX = # Of Bands (-1) to set + 045D 75 02 JNZ @DL_LONGLN ; jump if longer than one segment + + 045F 22 DF AND BL, BH ; otherwise, merge clip masks + + 0461 @DL_LONGLN: + + OUT_8 SC_Data, BL ; Set the Left Clip Mask + 0461 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0464 8A C3 1 MOV AL, BL ; then Get Data Value + 0466 EE 1 OUT DX, AL ; Set I/O Register + + 0467 8A 46 0A MOV AL, [BP].DL_ColorF ; Get Line Color + 046A 8A D8 MOV BL, AL ; BL = Copy of Line Color + 046C AA STOSB ; Set Left (1-4) Pixels + + 046D E3 55 JCXZ @DL_EXIT ; Done if only one Line Segment + + 046F 49 DEC CX ; CX = # of Middle Segments + 0470 74 07 JZ @DL_XRSEG ; If no middle segments.... + + ; Draw Middle Segments + + OUT_8 DX, ALL_PLANES ; Write to ALL Planes + 0472 B0 0F 1 MOV AL, ALL_PLANES ; then Get Data Value + 0474 EE 1 OUT DX, AL ; Set I/O Register + + 0475 8A C3 MOV AL, BL ; Get Color from BL + 0477 F3/ AA REP STOSB ; Draw Middle (4 Pixel) Segments + + 0479 @DL_XRSEG: + OUT_8 DX, BH ; Select Planes for Right Clip Mask + 0479 8A C7 1 MOV AL, BH ; then Get Data Value + 047B EE 1 OUT DX, AL ; Set I/O Register + 047C 8A C3 MOV AL, BL ; Get Color Value + 047E AA STOSB ; Draw Right (1-4) Pixels + + 047F EB 43 JMP s @DL_EXIT ; We Are Done... + + + ; This Code Draws A Vertical Line. On entry: + ; CH = Line Color, SI & DI = X1 + + 0481 @DL_VLINE: + + 0481 8B 46 10 MOV AX, [BP].DL_Ypos1 ; AX = Y1 + 0484 8B 76 0C MOV SI, [BP].DL_Ypos2 ; SI = Y2 + 0487 3B C6 CMP AX, SI ; Is Y1 < Y2? + 0489 7E 01 JLE @DL_NOSWAP2 ; if so, Don't Swap them + + 048B 96 XCHG AX, SI ; Ok, NOW Y1 < Y2 + + 048C @DL_NOSWAP2: + + 048C 2B F0 SUB SI, AX ; SI = Line Height (Y2-Y1+1) + 048E 46 INC SI + + ; AX = Y1, DI = X1, Get offset into Page into AX + + 048F F7 26 0000 R MUL SCREEN_WIDTH ; Offset = Y1 (AX) * Screen Width + 0493 8B D7 MOV DX, DI ; Copy Xpos into DX + 0495 C1 EF 02 SHR DI, 2 ; DI = Xpos/4 + 0498 03 C7 ADD AX, DI ; DI = Xpos/4 + ScreenWidth * Y1 + + 049A C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + 049E 03 F8 ADD DI, AX ; Point to Pixel X1, Y1 + + ;Select Plane + + 04A0 8A CA MOV CL, DL ; CL = Save X1 + 04A2 80 E1 03 AND CL, PLANE_BITS ; Get X1 MOD 4 (Plane #) + 04A5 B8 0102 MOV AX, MAP_MASK_PLANE1 ; Code to set Plane #1 + 04A8 D2 E4 SHL AH, CL ; Change to Correct Plane # + OUT_16 SC_Index, AX ; Select Plane + 04AA BA 03C4 1 MOV DX, SC_Index ; then Select Register + 04AD EF 1 OUT DX, AX ; Set I/O Register(s) + + 04AE 8A C5 MOV AL, CH ; Get Saved Color + 04B0 8B 1E 0000 R MOV BX, SCREEN_WIDTH ; Get Offset to Advance Line By + + 04B4 @DL_VLoop: + 04B4 26: 88 05 MOV ES:[DI], AL ; Draw Single Pixel + 04B7 03 FB ADD DI, BX ; Point to Next Line + LOOPjz SI, @DL_EXIT ; Lines--, Exit if done + 04B9 4E 1 DEC SI ; Counter-- + 04BA 74 08 1 JZ @DL_EXIT ; Jump if 0 + + 04BC 26: 88 05 MOV ES:[DI], AL ; Draw Single Pixel + 04BF 03 FB ADD DI, BX ; Point to Next Line + LOOPx SI, @DL_VLoop ; Lines--, Loop until Done + 04C1 4E 1 DEC SI ; Counter-- + 04C2 75 F0 1 JNZ @DL_VLoop ; Jump if not 0 + + 04C4 @DL_EXIT: + + 04C4 E9 0157 JMP @DL_EXIT2 ; Done! + + ; This code Draws a diagonal line in Mode X + + 04C7 @DL_BREZHAM: + 04C7 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 04CB 8B 46 10 MOV AX, [BP].DL_Ypos1 ; get Y1 value + 04CE 8B 5E 0C MOV BX, [BP].DL_Ypos2 ; get Y2 value + 04D1 8B 4E 12 MOV CX, [BP].DL_Xpos1 ; Get Starting Xpos + + 04D4 3B D8 CMP BX, AX ; Y2-Y1 is? + 04D6 73 04 JNC @DL_DeltaYOK ; if Y2>=Y1 then goto... + + 04D8 93 XCHG BX, AX ; Swap em... + 04D9 8B 4E 0E MOV CX, [BP].DL_Xpos2 ; Get New Starting Xpos + + 04DC @DL_DeltaYOK: + 04DC F7 26 0000 R MUL SCREEN_WIDTH ; Offset = SCREEN_WIDTH * Y1 + + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 6 - 1 + + + 04E0 03 F8 ADD DI, AX ; DI -> Start of Line Y1 on Page + 04E2 8B C1 MOV AX, CX ; AX = Xpos (X1) + 04E4 C1 E8 02 SHR AX, 2 ; /4 = Byte Offset into Line + 04E7 03 F8 ADD DI, AX ; DI = Starting pos (X1,Y1) + + 04E9 B0 11 MOV AL, 11h ; Staring Mask + 04EB 80 E1 03 AND CL, PLANE_BITS ; Get Plane # + 04EE D2 E0 SHL AL, CL ; and shift into place + 04F0 8A 66 0A MOV AH, [BP].DL_ColorF ; Color in Hi Bytes + + 04F3 50 PUSH AX ; Save Mask,Color... + + 04F4 8A E0 MOV AH, AL ; Plane # in AH + 04F6 B0 02 MOV AL, MAP_MASK ; Select Plane Register + OUT_16 SC_Index, AX ; Select initial plane + 04F8 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 04FB EF 1 OUT DX, AX ; Set I/O Register(s) + + 04FC 8B 46 12 MOV AX, [BP].DL_Xpos1 ; get X1 value + 04FF 8B 5E 10 MOV BX, [BP].DL_Ypos1 ; get Y1 value + 0502 8B 4E 0E MOV CX, [BP].DL_Xpos2 ; get X2 value + 0505 8B 56 0C MOV DX, [BP].DL_Ypos2 ; get Y2 value + + 0508 8B 2E 0000 R MOV BP, SCREEN_WIDTH ; Use BP for Line width to + ; to avoid extra memory access + + 050C 2B D3 SUB DX, BX ; figure Delta_Y + 050E 73 05 JNC @DL_DeltaYOK2 ; jump if Y2 >= Y1 + + 0510 03 DA ADD BX, DX ; put Y2 into Y1 + 0512 F7 DA NEG DX ; abs(Delta_Y) + 0514 91 XCHG AX, CX ; and exchange X1 and X2 + + 0515 @DL_DeltaYOK2: + 0515 BB 8000 MOV BX, 08000H ; seed for fraction accumulator + + 0518 2B C8 SUB CX, AX ; figure Delta_X + 051A 72 03 JC @DL_DrawLeft ; if negative, go left + + 051C E9 0084 JMP @DL_DrawRight ; Draw Line that slopes right + + 051F @DL_DrawLeft: + + 051F F7 D9 NEG CX ; abs(Delta_X) + + 0521 3B CA CMP CX, DX ; is Delta_X < Delta_Y? + 0523 72 41 JB @DL_SteepLeft ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the left in Mode X + + 0525 @DL_ShallowLeft: + CLR AX ; zero low word of Delta_Y * 10000h + 0525 33 C0 1 XOR AX, AX ; Set Register = 0 + 0527 2B C2 SUB AX, DX ; DX:AX <- DX * 0FFFFh + 0529 83 DA 00 SBB DX, 0 ; include carry + 052C F7 F1 DIV CX ; divide by Delta_X + + 052E 8B F3 MOV SI, BX ; SI = Accumulator + 0530 8B D8 MOV BX, AX ; BX = Add fraction + 0532 58 POP AX ; Get Color, Bit mask + 0533 BA 03C5 MOV DX, SC_Data ; Sequence controller data register + 0536 41 INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Left, and Maybe Down... + + 0537 @DL_SLLLoop: + 0537 26: 88 25 MOV ES:[DI], AH ; set first pixel, plane data set up + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + 053A 49 1 DEC CX ; Counter-- + 053B 74 26 1 JZ @DL_SLLExit ; Jump if 0 + + 053D 03 F3 ADD SI, BX ; add numerator to accumulator + 053F 73 02 JNC @DL_SLLL2nc ; move down on carry + + 0541 03 FD ADD DI, BP ; Move Down one line... + + 0543 @DL_SLLL2nc: + 0543 4F DEC DI ; Left one addr + 0544 D0 C8 ROR AL, 1 ; Move Left one plane, back on 0 1 2 + 0546 3C 87 CMP AL, 87h ; wrap?, if AL <88 then Carry set + 0548 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 054B EE OUT DX, AL ; Set up New Bit Plane mask + + 054C 26: 88 25 MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLLExit ; Delta_X--, Exit if done + 054F 49 1 DEC CX ; Counter-- + 0550 74 11 1 JZ @DL_SLLExit ; Jump if 0 + + 0552 03 F3 ADD SI, BX ; add numerator to accumulator, + 0554 73 02 JNC @DL_SLLL3nc ; move down on carry + + 0556 03 FD ADD DI, BP ; Move Down one line... + + 0558 @DL_SLLL3nc: ; Now move left a pixel... + 0558 4F DEC DI ; Left one addr + 0559 D0 C8 ROR AL, 1 ; Move Left one plane, back on 0 1 2 + 055B 3C 87 CMP AL, 87h ; Wrap?, if AL <88 then Carry set + 055D 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 0560 EE OUT DX, AL ; Set up New Bit Plane mask + 0561 EB D4 JMP s @DL_SLLLoop ; loop until done + + 0563 @DL_SLLExit: + 0563 E9 00B8 JMP @DL_EXIT2 ; and exit + + ; Draw a steep line to the left in Mode X + + 0566 @DL_SteepLeft: + CLR AX ; zero low word of Delta_Y * 10000h + 0566 33 C0 1 XOR AX, AX ; Set Register = 0 + 0568 87 D1 XCHG DX, CX ; Delta_Y switched with Delta_X + 056A F7 F1 DIV CX ; divide by Delta_Y + + 056C 8B F3 MOV SI, BX ; SI = Accumulator + 056E 8B D8 MOV BX, AX ; BX = Add Fraction + 0570 58 POP AX ; Get Color, Bit mask + 0571 BA 03C5 MOV DX, SC_Data ; Sequence controller data register + 0574 41 INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe left + + 0575 @DL_STLLoop: + + 0575 26: 88 25 MOV ES:[DI], AH ; set first pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + 0578 49 1 DEC CX ; Counter-- + 0579 74 26 1 JZ @DL_STLExit ; Jump if 0 + + 057B 03 F3 ADD SI, BX ; add numerator to accumulator + 057D 73 09 JNC @DL_STLnc2 ; No carry, just move down! + + 057F 4F DEC DI ; Move Left one addr + 0580 D0 C8 ROR AL, 1 ; Move Left one plane, back on 0 1 2 + 0582 3C 87 CMP AL, 87h ; Wrap?, if AL <88 then Carry set + 0584 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 0587 EE OUT DX, AL ; Set up New Bit Plane mask + + 0588 @DL_STLnc2: + 0588 03 FD ADD DI, BP ; advance to next line. + + 058A 26: 88 25 MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_STLExit ; Delta_Y--, Exit if done + 058D 49 1 DEC CX ; Counter-- + 058E 74 11 1 JZ @DL_STLExit ; Jump if 0 + + 0590 03 F3 ADD SI, BX ; add numerator to accumulator + 0592 73 09 JNC @DL_STLnc3 ; No carry, just move down! + + 0594 4F DEC DI ; Move Left one addr + 0595 D0 C8 ROR AL, 1 ; Move Left one plane, back on 0 1 2 + 0597 3C 87 CMP AL, 87h ; Wrap?, if AL <88 then Carry set + 0599 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 059C EE OUT DX, AL ; Set up New Bit Plane mask + + 059D @DL_STLnc3: + 059D 03 FD ADD DI, BP ; advance to next line. + 059F EB D4 JMP s @DL_STLLoop ; Loop until done + + 05A1 @DL_STLExit: + 05A1 EB 7B JMP @DL_EXIT2 ; and exit + + ; Draw a line that goes to the Right... + + 05A3 @DL_DrawRight: + 05A3 3B CA CMP CX, DX ; is Delta_X < Delta_Y? + 05A5 72 3E JB @DL_SteepRight ; yes, so go do steep line + ; (Delta_Y iterations) + + ; Draw a Shallow line to the Right in Mode X + + 05A7 @DL_ShallowRight: + CLR AX ; zero low word of Delta_Y * 10000h + 05A7 33 C0 1 XOR AX, AX ; Set Register = 0 + 05A9 2B C2 SUB AX, DX ; DX:AX <- DX * 0FFFFh + 05AB 83 DA 00 SBB DX, 0 ; include carry + 05AE F7 F1 DIV CX ; divide by Delta_X + + 05B0 8B F3 MOV SI, BX ; SI = Accumulator + 05B2 8B D8 MOV BX, AX ; BX = Add Fraction + 05B4 58 POP AX ; Get Color, Bit mask + 05B5 BA 03C5 MOV DX, SC_Data ; Sequence controller data register + 05B8 41 INC CX ; Inc Delta_X so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Right, and Maybe Down... + + 05B9 @DL_SLRLoop: + 05B9 26: 88 25 MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + 05BC 49 1 DEC CX ; Counter-- + 05BD 74 24 1 JZ @DL_SLRExit ; Jump if 0 + + 05BF 03 F3 ADD SI, BX ; add numerator to accumulator + 05C1 73 02 JNC @DL_SLR2nc ; don't move down if carry not set + + 05C3 03 FD ADD DI, BP ; Move Down one line... + + 05C5 @DL_SLR2nc: ; Now move right a pixel... + 05C5 D0 C0 ROL AL, 1 ; Move Right one addr if Plane = 0 + 05C7 3C 12 CMP AL, 12h ; Wrap? if AL >12 then Carry not set + 05C9 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 05CC EE OUT DX, AL ; Set up New Bit Plane mask + + 05CD 26: 88 25 MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_SLRExit ; Delta_X--, Exit if done.. + 05D0 49 1 DEC CX ; Counter-- + 05D1 74 10 1 JZ @DL_SLRExit ; Jump if 0 + + 05D3 03 F3 ADD SI, BX ; add numerator to accumulator + 05D5 73 02 JNC @DL_SLR3nc ; don't move down if carry not set + + 05D7 03 FD ADD DI, BP ; Move Down one line... + + 05D9 @DL_SLR3nc: + 05D9 D0 C0 ROL AL, 1 ; Move Right one addr if Plane = 0 + 05DB 3C 12 CMP AL, 12h ; Wrap? if AL >12 then Carry not set + 05DD 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 05E0 EE OUT DX, AL ; Set up New Bit Plane mask + 05E1 EB D6 JMP s @DL_SLRLoop ; loop till done + + 05E3 @DL_SLRExit: + 05E3 EB 39 JMP @DL_EXIT2 ; and exit + + ; Draw a Steep line to the Right in Mode X + + 05E5 @DL_SteepRight: + CLR AX ; zero low word of Delta_Y * 10000h + 05E5 33 C0 1 XOR AX, AX ; Set Register = 0 + 05E7 87 D1 XCHG DX, CX ; Delta_Y switched with Delta_X + 05E9 F7 F1 DIV CX ; divide by Delta_Y + + 05EB 8B F3 MOV SI, BX ; SI = Accumulator + 05ED 8B D8 MOV BX, AX ; BX = Add Fraction + 05EF 58 POP AX ; Get Color, Bit mask + 05F0 BA 03C5 MOV DX, SC_Data ; Sequence controller data register + 05F3 41 INC CX ; Inc Delta_Y so we can unroll loop + + ; Loop (x2) to Draw Pixels, Move Down, and Maybe Right + + 05F4 @STRLoop: + 05F4 26: 88 25 MOV ES:[DI], AH ; set first pixel, mask is set up + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + 05F7 49 1 DEC CX ; Counter-- + 05F8 74 24 1 JZ @DL_EXIT2 ; Jump if 0 + + 05FA 03 F3 ADD SI, BX ; add numerator to accumulator + 05FC 73 08 JNC @STRnc2 ; if no carry then just go down... + + 05FE D0 C0 ROL AL, 1 ; Move Right one addr if Plane = 0 + 0600 3C 12 CMP AL, 12h ; Wrap? if AL >12 then Carry not set + 0602 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 0605 EE OUT DX, AL ; Set up New Bit Plane mask + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 7 - 1 + + + + 0606 @STRnc2: + 0606 03 FD ADD DI, BP ; advance to next line. + + 0608 26: 88 25 MOV ES:[DI], AH ; set pixel + LOOPjz CX, @DL_EXIT2 ; Delta_Y--, Exit if Done + 060B 49 1 DEC CX ; Counter-- + 060C 74 10 1 JZ @DL_EXIT2 ; Jump if 0 + + 060E 03 F3 ADD SI, BX ; add numerator to accumulator + 0610 73 08 JNC @STRnc3 ; if no carry then just go down... + + 0612 D0 C0 ROL AL, 1 ; Move Right one addr if Plane = 0 + 0614 3C 12 CMP AL, 12h ; Wrap? if AL >12 then Carry not set + 0616 83 D7 00 ADC DI, 0 ; Adjust Address: DI = DI + Carry + 0619 EE OUT DX, AL ; Set up New Bit Plane mask + + 061A @STRnc3: + 061A 03 FD ADD DI, BP ; advance to next line. + 061C EB D6 JMP s @STRLoop ; loop till done + + 061E @DL_EXIT2: + POPx DI, SI, BP ; Restore Saved Registers + 061E 5F 1 POP DI ; Restore R1 + 061F 5E 2 POP SI ; Restore R1 + 0620 5D 3 POP BP ; Restore R1 + 0621 CA 000A RET 10 ; Exit and Clean up Stack + + 0624 DRAW_LINE ENDP + + + ; ===== DAC COLOR REGISTER ROUTINES ===== + + ;================================================= + ;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%) + ;================================================= + ; + ; Sets a single (RGB) Vga Palette Register + ; + ; ENTRY: Register = The DAC # to modify (0-255) + ; Red = The new Red Intensity (0-63) + ; Green = The new Green Intensity (0-63) + ; Blue = The new Blue Intensity (0-63) + ; + ; EXIT: No meaningful values returned + ; + + 000E SDR_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 00 00 SDR_Blue DB ?,? ; Blue Data Value + 0008 00 00 SDR_Green DB ?,? ; Green Data Value + 000A 00 00 SDR_Red DB ?,? ; Red Data Value + 000C 00 00 SDR_Register DB ?,? ; Palette Register # + SDR_STACK ENDS + + PUBLIC SET_DAC_REGISTER + + 0624 SET_DAC_REGISTER PROC FAR + + 0624 55 PUSH BP ; Save BP + 0625 8B EC MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to modify + + OUT_8 DAC_WRITE_ADDR, [BP].SDR_Register + 0627 BA 03C8 1 MOV DX, DAC_WRITE_ADDR ; then Select Register + 062A 8A 46 0C 1 MOV AL, [BP].SDR_Register ; then Get Data Value + 062D EE 1 OUT DX, AL ; Set I/O Register + + 062E BA 03C9 MOV DX, PEL_DATA_REG ; Dac Data Register + OUT_8 DX, [BP].SDR_Red ; Set Red Intensity + 0631 8A 46 0A 1 MOV AL, [BP].SDR_Red ; then Get Data Value + 0634 EE 1 OUT DX, AL ; Set I/O Register + OUT_8 DX, [BP].SDR_Green ; Set Green Intensity + 0635 8A 46 08 1 MOV AL, [BP].SDR_Green ; then Get Data Value + 0638 EE 1 OUT DX, AL ; Set I/O Register + OUT_8 DX, [BP].SDR_Blue ; Set Blue Intensity + 0639 8A 46 06 1 MOV AL, [BP].SDR_Blue ; then Get Data Value + 063C EE 1 OUT DX, AL ; Set I/O Register + + 063D 5D POP BP ; Restore Registers + 063E CA 0008 RET 8 ; Exit & Clean Up Stack + + 0641 SET_DAC_REGISTER ENDP + + ;==================================================== + ;GET_DAC_REGISTER (Register%, &Red%, &Green%, &Blue%) + ;==================================================== + ; + ; Reads the RGB Values of a single Vga Palette Register + ; + ; ENTRY: Register = The DAC # to read (0-255) + ; Red = Offset to Red Variable in DS + ; Green = Offset to Green Variable in DS + ; Blue = Offset to Blue Variable in DS + ; + ; EXIT: The values of the integer variables Red, + ; Green, and Blue are set to the values + ; taken from the specified DAC register. + ; + + 000E GDR_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 GDR_Blue DW ? ; Addr of Blue Data Value in DS + 0008 0000 GDR_Green DW ? ; Addr of Green Data Value in DS + 000A 0000 GDR_Red DW ? ; Addr of Red Data Value in DS + 000C 00 00 GDR_Register DB ?,? ; Palette Register # + GDR_STACK ENDS + + PUBLIC GET_DAC_REGISTER + + 0641 GET_DAC_REGISTER PROC FAR + + 0641 55 PUSH BP ; Save BP + 0642 8B EC MOV BP, SP ; Set up Stack Frame + + ; Select which DAC Register to read in + + OUT_8 DAC_READ_ADDR, [BP].GDR_Register + 0644 BA 03C7 1 MOV DX, DAC_READ_ADDR ; then Select Register + 0647 8A 46 0C 1 MOV AL, [BP].GDR_Register ; then Get Data Value + 064A EE 1 OUT DX, AL ; Set I/O Register + + 064B BA 03C9 MOV DX, PEL_DATA_REG ; Dac Data Register + CLR AX ; Clear AX + 064E 33 C0 1 XOR AX, AX ; Set Register = 0 + + 0650 EC IN AL, DX ; Read Red Value + 0651 8B 5E 0A MOV BX, [BP].GDR_Red ; Get Address of Red% + 0654 89 07 MOV [BX], AX ; *Red% = AX + + 0656 EC IN AL, DX ; Read Green Value + 0657 8B 5E 08 MOV BX, [BP].GDR_Green ; Get Address of Green% + 065A 89 07 MOV [BX], AX ; *Green% = AX + + 065C EC IN AL, DX ; Read Blue Value + 065D 8B 5E 06 MOV BX, [BP].GDR_Blue ; Get Address of Blue% + 0660 89 07 MOV [BX], AX ; *Blue% = AX + + 0662 5D POP BP ; Restore Registers + 0663 CA 0008 RET 8 ; Exit & Clean Up Stack + + 0666 GET_DAC_REGISTER ENDP + + + ;=========================================================== + ;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%) + ;=========================================================== + ; + ; Sets a Block of Vga Palette Registers + ; + ; ENTRY: PalData = Far Pointer to Block of palette data + ; StartReg = First Register # in range to set (0-255) + ; EndReg = Last Register # in Range to set (0-255) + ; Sync = Wait for Vertical Retrace Flag (Boolean) + ; + ; EXIT: No meaningful values returned + ; + ; NOTES: PalData is a linear array of 3 byte Palette values + ; in the order: Red (0-63), Green (0-63), Blue (0-63) + ; + + 0014 LDR_STACK STRUC + 0000 0000 0000 0000 DW ?x3 ; BP, DS, SI + 0006 00000000 DD ? ; Caller + 000A 0000 LDR_Sync DW ? ; Vertical Sync Flag + 000C 00 00 LDR_EndReg DB ?,? ; Last Register # + 000E 00 00 LDR_StartReg DB ?,? ; First Register # + 0010 00000000 LDR_PalData DD ? ; Far Ptr to Palette Data + LDR_STACK ENDS + + PUBLIC LOAD_DAC_REGISTERS + + 0666 LOAD_DAC_REGISTERS PROC FAR + + PUSHx BP, DS, SI ; Save Registers + 0666 55 1 PUSH BP ; Save R1 + 0667 1E 2 PUSH DS ; Save R1 + 0668 56 3 PUSH SI ; Save R1 + 0669 8B EC mov BP, SP ; Set up Stack Frame + + 066B 8B 46 0A mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag + 066E 0B C0 or AX, AX ; is Sync Flag = 0? + 0670 74 05 jz @LDR_Load ; if so, skip call + + 0672 9A ---- 0795 R call f SYNC_DISPLAY ; wait for vsync + + ; Determine register #'s, size to copy, etc + + 0677 @LDR_Load: + + 0677 C5 76 10 lds SI, [BP].LDR_PalData ; DS:SI -> Palette Data + 067A BA 03C8 mov DX, DAC_WRITE_ADDR ; DAC register # selector + + CLR AX, BX ; Clear for byte loads + 067D 33 C0 1 XOR AX, AX ; Set Register = 0 + 067F 33 DB 2 XOR BX, BX ; Set Register = 0 + 0681 8A 46 0E mov AL, [BP].LDR_StartReg ; Get Start Register + 0684 8A 5E 0C mov BL, [BP].LDR_EndReg ; Get End Register + + 0687 2B D8 sub BX, AX ; BX = # of DAC registers -1 + 0689 43 inc BX ; BX = # of DAC registers + 068A 8B CB mov CX, BX ; CX = # of DAC registers + 068C 03 CB add CX, BX ; CX = " " * 2 + 068E 03 CB add CX, BX ; CX = " " * 3 + 0690 FC cld ; Block OUTs forward + 0691 EE out DX, AL ; set up correct register # + + ; Load a block of DAC Registers + + 0692 BA 03C9 mov DX, PEL_DATA_REG ; Dac Data Register + + 0695 F3/ 6E rep outsb ; block set DAC registers + + POPx SI, DS, BP ; Restore Registers + 0697 5E 1 POP SI ; Restore R1 + 0698 1F 2 POP DS ; Restore R1 + 0699 5D 3 POP BP ; Restore R1 + 069A CA 000A ret 10 ; Exit & Clean Up Stack + + 069D LOAD_DAC_REGISTERS ENDP + + + ;==================================================== + ;READ_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%) + ;==================================================== + ; + ; Reads a Block of Vga Palette Registers + ; + ; ENTRY: PalData = Far Pointer to block to store palette data + ; StartReg = First Register # in range to read (0-255) + ; EndReg = Last Register # in Range to read (0-255) + ; + ; EXIT: No meaningful values returned + ; + ; NOTES: PalData is a linear array of 3 byte Palette values + ; in the order: Red (0-63), Green (0-63), Blue (0-63) + ; + + 0012 RDR_STACK STRUC + 0000 0000 0000 0000 DW ?x3 ; BP, ES, DI + 0006 00000000 DD ? ; Caller + 000A 00 00 RDR_EndReg DB ?,? ; Last Register # + 000C 00 00 RDR_StartReg DB ?,? ; First Register # + 000E 00000000 RDR_PalData DD ? ; Far Ptr to Palette Data + RDR_STACK ENDS + + PUBLIC READ_DAC_REGISTERS + + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 8 - 1 + + + 069D READ_DAC_REGISTERS PROC FAR + + PUSHx BP, ES, DI ; Save Registers + 069D 55 1 PUSH BP ; Save R1 + 069E 06 2 PUSH ES ; Save R1 + 069F 57 3 PUSH DI ; Save R1 + 06A0 8B EC mov BP, SP ; Set up Stack Frame + + ; Determine register #'s, size to copy, etc + + 06A2 C4 7E 0E les DI, [BP].RDR_PalData ; ES:DI -> Palette Buffer + 06A5 BA 03C7 mov DX, DAC_READ_ADDR ; DAC register # selector + + CLR AX, BX ; Clear for byte loads + 06A8 33 C0 1 XOR AX, AX ; Set Register = 0 + 06AA 33 DB 2 XOR BX, BX ; Set Register = 0 + 06AC 8A 46 0C mov AL, [BP].RDR_StartReg ; Get Start Register + 06AF 8A 5E 0A mov BL, [BP].RDR_EndReg ; Get End Register + + 06B2 2B D8 sub BX, AX ; BX = # of DAC registers -1 + 06B4 43 inc BX ; BX = # of DAC registers + 06B5 8B CB mov CX, BX ; CX = # of DAC registers + 06B7 03 CB add CX, BX ; CX = " " * 2 + 06B9 03 CB add CX, BX ; CX = " " * 3 + 06BB FC cld ; Block INs forward + + ; Read a block of DAC Registers + + 06BC EE out DX, AL ; set up correct register # + 06BD BA 03C9 mov DX, PEL_DATA_REG ; Dac Data Register + + 06C0 F3/ 6C rep insb ; block read DAC registers + + POPx DI, ES, BP ; Restore Registers + + 06C2 5F 1 POP DI ; Restore R1 + 06C3 07 2 POP ES ; Restore R1 + 06C4 5D 3 POP BP ; Restore R1 + 06C5 CA 0008 ret 8 ; Exit & Clean Up Stack + + 06C8 READ_DAC_REGISTERS ENDP + + + ; ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== + + ;========================= + ;SET_ACTIVE_PAGE (PageNo%) + ;========================= + ; + ; Sets the active display Page to be used for future drawing + ; + ; ENTRY: PageNo = Display Page to make active + ; (values: 0 to Number of Pages - 1) + ; + ; EXIT: No meaningful values returned + ; + + 0008 SAP_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 SAP_Page DW ? ; Page # for Drawing + SAP_STACK ENDS + + PUBLIC SET_ACTIVE_PAGE + + 06C8 SET_ACTIVE_PAGE PROC FAR + + 06C8 55 PUSH BP ; Preserve Registers + 06C9 8B EC MOV BP, SP ; Set up Stack Frame + + 06CB 8B 5E 06 MOV BX, [BP].SAP_Page ; Get Desired Page # + 06CE 3B 1E 0004 R CMP BX, LAST_PAGE ; Is Page # Valid? + 06D2 73 0D JAE @SAP_Exit ; IF Not, Do Nothing + + 06D4 89 1E 0012 R MOV ACTIVE_PAGE, BX ; Set Active Page # + + 06D8 D1 E3 SHL BX, 1 ; Scale Page # to Word + 06DA 8B 87 0006 R MOV AX, PAGE_ADDR[BX] ; Get offset to Page + + 06DE A3 0014 R MOV CURRENT_PAGE, AX ; And set for future LES's + + 06E1 @SAP_Exit: + 06E1 5D POP BP ; Restore Registers + 06E2 CA 0002 RET 2 ; Exit and Clean up Stack + + 06E5 SET_ACTIVE_PAGE ENDP + + + ;================ + ;GET_ACTIVE_PAGE% + ;================ + ; + ; Returns the Video Page # currently used for Drawing + ; + ; ENTRY: No Parameters are passed + ; + ; EXIT: AX = Current Video Page used for Drawing + ; + + PUBLIC GET_ACTIVE_PAGE + + 06E5 GET_ACTIVE_PAGE PROC FAR + + 06E5 A1 0012 R MOV AX, ACTIVE_PAGE ; Get Active Page # + 06E8 CB RET ; Exit and Clean up Stack + + 06E9 GET_ACTIVE_PAGE ENDP + + + ;=============================== + ;SET_DISPLAY_PAGE (DisplayPage%) + ;=============================== + ; + ; Sets the currently visible display page. + ; When called this routine syncronizes the display + ; to the vertical blank. + ; + ; ENTRY: PageNo = Display Page to show on the screen + ; (values: 0 to Number of Pages - 1) + ; + ; EXIT: No meaningful values returned + ; + + 0008 SDP_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 SDP_Page DW ? ; Page # to Display... + SDP_STACK ENDS + + PUBLIC SET_DISPLAY_PAGE + + 06E9 SET_DISPLAY_PAGE PROC FAR + + 06E9 55 PUSH BP ; Preserve Registers + 06EA 8B EC MOV BP, SP ; Set up Stack Frame + + 06EC 8B 5E 06 MOV BX, [BP].SDP_Page ; Get Desired Page # + 06EF 3B 1E 0004 R CMP BX, LAST_PAGE ; Is Page # Valid? + 06F3 73 2B JAE @SDP_Exit ; IF Not, Do Nothing + + 06F5 89 1E 0010 R MOV DISPLAY_PAGE, BX ; Set Display Page # + + 06F9 D1 E3 SHL BX, 1 ; Scale Page # to Word + 06FB 8B 8F 0006 R MOV CX, PAGE_ADDR[BX] ; Get offset in memory to Page + 06FF 03 0E 001C R ADD CX, CURRENT_MOFFSET ; Adjust for any scrolling + + ; Wait if we are currently in a Vertical Retrace + + 0703 BA 03DA MOV DX, INPUT_1 ; Input Status #1 Register + + 0706 @DP_WAIT0: + 0706 EC IN AL, DX ; Get VGA status + 0707 24 08 AND AL, VERT_RETRACE ; In Display mode yet? + 0709 75 FB JNZ @DP_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new page + + 070B BA 03D4 MOV DX, CRTC_Index ; We Change the VGA Sequencer + + 070E B0 0D MOV AL, START_DISP_LO ; Display Start Low Register + 0710 8A E1 MOV AH, CL ; Low 8 Bits of Start Addr + 0712 EF OUT DX, AX ; Set Display Addr Low + + 0713 B0 0C MOV AL, START_DISP_HI ; Display Start High Register + 0715 8A E5 MOV AH, CH ; High 8 Bits of Start Addr + 0717 EF OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + 0718 BA 03DA MOV DX, INPUT_1 ; Input Status #1 Register + + 071B @DP_WAIT1: + 071B EC IN AL, DX ; Get VGA status + 071C 24 08 AND AL, VERT_RETRACE ; Vertical Retrace Start? + 071E 74 FB JZ @DP_WAIT1 ; If Not, wait for it + + ; Now Set Display Starting Address + + + 0720 @SDP_Exit: + 0720 5D POP BP ; Restore Registers + 0721 CA 0002 RET 2 ; Exit and Clean up Stack + + 0724 SET_DISPLAY_PAGE ENDP + + + ;================= + ;GET_DISPLAY_PAGE% + ;================= + ; + ; Returns the Video Page # currently displayed + ; + ; ENTRY: No Parameters are passed + ; + ; EXIT: AX = Current Video Page being displayed + ; + + PUBLIC GET_DISPLAY_PAGE + + 0724 GET_DISPLAY_PAGE PROC FAR + + 0724 A1 0010 R MOV AX, DISPLAY_PAGE ; Get Display Page # + 0727 CB RET ; Exit & Clean Up Stack + + 0728 GET_DISPLAY_PAGE ENDP + + + ;======================================= + ;SET_WINDOW (DisplayPage%, Xpos%, Ypos%) + ;======================================= + ; + ; Since a Logical Screen can be larger than the Physical + ; Screen, Scrolling is possible. This routine sets the + ; Upper Left Corner of the Screen to the specified Pixel. + ; Also Sets the Display page to simplify combined page + ; flipping and scrolling. When called this routine + ; syncronizes the display to the vertical blank. + ; + ; ENTRY: DisplayPage = Display Page to show on the screen + ; Xpos = # of pixels to shift screen right + ; Ypos = # of lines to shift screen down + ; + ; EXIT: No meaningful values returned + ; + + 000C SW_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 SW_Ypos DW ? ; Y pos of UL Screen Corner + 0008 0000 SW_Xpos DW ? ; X pos of UL Screen Corner + 000A 0000 SW_Page DW ? ; (new) Display Page + SW_STACK ENDS + + PUBLIC SET_WINDOW + + 0728 SET_WINDOW PROC FAR + + 0728 55 PUSH BP ; Preserve Registers + 0729 8B EC MOV BP, SP ; Set up Stack Frame + + ; Check if our Scroll Offsets are Valid + + 072B 8B 5E 0A MOV BX, [BP].SW_Page ; Get Desired Page # + 072E 3B 1E 0004 R CMP BX, LAST_PAGE ; Is Page # Valid? + 0732 73 55 JAE @SW_Exit ; IF Not, Do Nothing + + 0734 8B 46 06 MOV AX, [BP].SW_Ypos ; Get Desired Y Offset + 0737 3B 06 0020 R CMP AX, MAX_YOFFSET ; Is it Within Limits? + 073B 77 4C JA @SW_Exit ; if not, exit + + 073D 8B 4E 08 MOV CX, [BP].SW_Xpos ; Get Desired X Offset + 0740 3B 0E 001E R CMP CX, MAX_XOFFSET ; Is it Within Limits? + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 9 - 1 + + + 0744 77 43 JA @SW_Exit ; if not, exit + + ; Compute proper Display start address to use + + 0746 F7 26 0000 R MUL SCREEN_WIDTH ; AX = YOffset * Line Width + 074A C1 E9 02 SHR CX, 2 ; CX / 4 = Bytes into Line + 074D 03 C1 ADD AX, CX ; AX = Offset of Upper Left Pixel + + 074F A3 001C R MOV CURRENT_MOFFSET, AX ; Save Offset Info + + 0752 89 1E 0010 R MOV DISPLAY_PAGE, BX ; Set Current Page # + 0756 D1 E3 SHL BX, 1 ; Scale Page # to Word + 0758 03 87 0006 R ADD AX, PAGE_ADDR[BX] ; Get offset in VGA to Page + 075C 8B D8 MOV BX, AX ; BX = Desired Display Start + + 075E BA 03DA MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait if we are currently in a Vertical Retrace + + 0761 @SW_WAIT0: + 0761 EC IN AL, DX ; Get VGA status + 0762 24 08 AND AL, VERT_RETRACE ; In Display mode yet? + 0764 75 FB JNZ @SW_WAIT0 ; If Not, wait for it + + ; Set the Start Display Address to the new window + + 0766 BA 03D4 MOV DX, CRTC_Index ; We Change the VGA Sequencer + 0769 B0 0D MOV AL, START_DISP_LO ; Display Start Low Register + 076B 8A E3 MOV AH, BL ; Low 8 Bits of Start Addr + 076D EF OUT DX, AX ; Set Display Addr Low + + 076E B0 0C MOV AL, START_DISP_HI ; Display Start High Register + 0770 8A E7 MOV AH, BH ; High 8 Bits of Start Addr + 0772 EF OUT DX, AX ; Set Display Addr High + + ; Wait for a Vertical Retrace to smooth out things + + 0773 BA 03DA MOV DX, INPUT_1 ; Input Status #1 Register + + 0776 @SW_WAIT1: + 0776 EC IN AL, DX ; Get VGA status + 0777 24 08 AND AL, VERT_RETRACE ; Vertical Retrace Start? + 0779 74 FB JZ @SW_WAIT1 ; If Not, wait for it + + ; Now Set the Horizontal Pixel Pan values + + OUT_8 ATTRIB_Ctrl, PIXEL_PAN_REG ; Select Pixel Pan Register + 077B BA 03C0 1 MOV DX, ATTRIB_Ctrl ; then Select Register + 077E B0 33 1 MOV AL, PIXEL_PAN_REG ; then Get Data Value + 0780 EE 1 OUT DX, AL ; Set I/O Register + + 0781 8B 46 08 MOV AX, [BP].SW_Xpos ; Get Desired X Offset + 0784 24 03 AND AL, 03 ; Get # of Pixels to Pan (0-3) + 0786 D0 E0 SHL AL, 1 ; Shift for 256 Color Mode + 0788 EE OUT DX, AL ; Fine tune the display! + + 0789 @SW_Exit: + 0789 5D POP BP ; Restore Saved Registers + 078A CA 0006 RET 6 ; Exit and Clean up Stack + + 078D SET_WINDOW ENDP + + + ;============= + ;GET_X_OFFSET% + ;============= + ; + ; Returns the X coordinate of the Pixel currently display + ; in the upper left corner of the display + ; + ; ENTRY: No Parameters are passed + ; + ; EXIT: AX = Current Horizontal Scroll Offset + ; + + PUBLIC GET_X_OFFSET + + 078D GET_X_OFFSET PROC FAR + + 078D A1 0018 R MOV AX, CURRENT_XOFFSET ; Get current horz offset + 0790 CB RET ; Exit & Clean Up Stack + + 0791 GET_X_OFFSET ENDP + + + ;============= + ;GET_Y_OFFSET% + ;============= + ; + ; Returns the Y coordinate of the Pixel currently display + ; in the upper left corner of the display + ; + ; ENTRY: No Parameters are passed + ; + ; EXIT: AX = Current Vertical Scroll Offset + ; + + PUBLIC GET_Y_OFFSET + + 0791 GET_Y_OFFSET PROC FAR + + 0791 A1 001A R MOV AX, CURRENT_YOFFSET ; Get current vertical offset + 0794 CB RET ; Exit & Clean Up Stack + + 0795 GET_Y_OFFSET ENDP + + + ;============ + ;SYNC_DISPLAY + ;============ + ; + ; Pauses the computer until the next Vertical Retrace starts + ; + ; ENTRY: No Parameters are passed + ; + ; EXIT: No meaningful values returned + ; + + PUBLIC SYNC_DISPLAY + + 0795 SYNC_DISPLAY PROC FAR + + 0795 BA 03DA MOV DX, INPUT_1 ; Input Status #1 Register + + ; Wait for any current retrace to end + + 0798 @SD_WAIT0: + 0798 EC IN AL, DX ; Get VGA status + 0799 24 08 AND AL, VERT_RETRACE ; In Display mode yet? + 079B 75 FB JNZ @SD_WAIT0 ; If Not, wait for it + + ; Wait for the start of the next vertical retrace + + 079D @SD_WAIT1: + 079D EC IN AL, DX ; Get VGA status + 079E 24 08 AND AL, VERT_RETRACE ; Vertical Retrace Start? + 07A0 74 FB JZ @SD_WAIT1 ; If Not, wait for it + + 07A2 CB RET ; Exit & Clean Up Stack + + 07A3 SYNC_DISPLAY ENDP + + + ; ===== TEXT DISPLAY ROUTINES ===== + + ;================================================== + ;GPRINTC (CharNum%, Xpos%, Ypos%, ColorF%, ColorB%) + ;================================================== + ; + ; Draws an ASCII Text Character using the currently selected + ; 8x8 font on the active display page. It would be a simple + ; exercise to make this routine process variable height fonts. + ; + ; ENTRY: CharNum = ASCII character # to draw + ; Xpos = X position to draw Character at + ; Ypos = Y position of to draw Character at + ; ColorF = Color to draw text character in + ; ColorB = Color to set background to + ; + ; EXIT: No meaningful values returned + ; + + 001E GPC_STACK STRUC + 0000 0000 GPC_Width DW ? ; Screen Width-1 + 0002 00 00 GPC_Lines DB ?,? ; Scan lines to Decode + 0004 0000 GPC_T_SETS DW ? ; Saved Charset Segment + 0006 0000 GPC_T_SETO DW ? ; Saved Charset Offset + 0008 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0010 00000000 DD ? ; Caller + 0014 00 00 GPC_ColorB DB ?,? ; Background Color + 0016 00 00 GPC_ColorF DB ?,? ; Text Color + 0018 0000 GPC_Ypos DW ? ; Y Position to Print at + 001A 0000 GPC_Xpos DW ? ; X position to Print at + 001C 00 00 GPC_Char DB ?,? ; Character to Print + GPC_STACK ENDS + + PUBLIC GPRINTC + + 07A3 GPRINTC PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 07A3 55 1 PUSH BP ; Save R1 + 07A4 1E 2 PUSH DS ; Save R1 + 07A5 56 3 PUSH SI ; Save R1 + 07A6 57 4 PUSH DI ; Save R1 + 07A7 83 EC 08 SUB SP, 8 ; Allocate WorkSpace on Stack + 07AA 8B EC MOV BP, SP ; Set up Stack Frame + + 07AC C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 07B0 A1 0000 R MOV AX, SCREEN_WIDTH ; Get Logical Line Width + 07B3 8B D8 MOV BX, AX ; BX = Screen Width + 07B5 4B DEC BX ; = Screen Width-1 + 07B6 89 5E 00 MOV [BP].GPC_Width, BX ; Save for later use + + 07B9 F7 66 18 MUL [BP].GPC_Ypos ; Start of Line = Ypos * Width + 07BC 03 F8 ADD DI, AX ; DI -> Start of Line Ypos + + 07BE 8B 46 1A MOV AX, [BP].GPC_Xpos ; Get Xpos of Character + 07C1 8B C8 MOV CX, AX ; Save Copy of Xpos + 07C3 C1 E8 02 SHR AX, 2 ; Bytes into Line = Xpos/4 + 07C6 03 F8 ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + 07C8 8A 46 1C MOV AL, [BP].GPC_Char ; Get Character # + 07CB A8 80 TEST AL, 080h ; Is Hi Bit Set? + 07CD 74 0C JZ @GPC_LowChar ; Nope, use low char set ptr + + 07CF 24 7F AND AL, 07Fh ; Mask Out Hi Bit + 07D1 8B 1E 0026 R MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + 07D5 8B 16 0028 R MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + 07D9 EB 08 JMP s @GPC_Set_Char ; Go Setup Character Ptr + + 07DB @GPC_LowChar: + + 07DB 8B 1E 0022 R MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + 07DF 8B 16 0024 R MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + + 07E3 @GPC_Set_Char: + 07E3 89 56 04 MOV [BP].GPC_T_SETS, DX ; Save Segment on Stack + + 07E6 B4 00 MOV AH, 0 ; Valid #'s are 0..127 + 07E8 C1 E0 03 SHL AX, 3 ; * 8 Bytes Per Bitmap + 07EB 03 D8 ADD BX, AX ; BX = Offset of Selected char + 07ED 89 5E 06 MOV [BP].GPC_T_SETO, BX ; Save Offset on Stack + + 07F0 83 E1 03 AND CX, PLANE_BITS ; Get Plane # + 07F3 B5 0F MOV CH, ALL_PLANES ; Get Initial Plane mask + 07F5 D2 E5 SHL CH, CL ; And shift into position + 07F7 80 E5 0F AND CH, ALL_PLANES ; And mask to lower nibble + + 07FA B0 04 MOV AL, 04 ; 4-Plane # = # of initial + 07FC 2A C1 SUB AL, CL ; shifts to align bit mask + 07FE 8A C8 MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + 0800 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 0803 B0 02 1 MOV AL, MAP_MASK ; then Get Data Value + 0805 EE 1 OUT DX, AL ; Set I/O Register + 0806 42 INC DX ; DX -> SC_Data + + 0807 B0 08 MOV AL, 08 ; 8 Lines to Process + 0809 88 46 02 MOV [BP].GPC_Lines, AL ; Save on Stack + + 080C 8E 5E 04 MOV DS, [BP].GPC_T_SETS ; Point to character set + + 080F @GPC_DECODE_CHAR_BYTE: + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 10 - 1 + + + + 080F 8B 76 06 MOV SI, [BP].GPC_T_SETO ; Get DS:SI = String + + 0812 8A 3C MOV BH, [SI] ; Get Bit Map + 0814 46 INC SI ; Point to Next Line + 0815 89 76 06 MOV [BP].GPC_T_SETO, SI ; And save new Pointer... + + CLR AX ; Clear AX + 0818 33 C0 1 XOR AX, AX ; Set Register = 0 + + CLR BL ; Clear BL + 081A 32 DB 1 XOR BL, BL ; Set Register = 0 + 081C D3 C3 ROL BX, CL ; BL holds left edge bits + 081E 8B F3 MOV SI, BX ; Use as Table Index + 0820 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + 0823 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 0828 74 07 JZ @GPC_NO_LEFT1BITS ; Skip if No Pixels to set + + 082A 8A 66 16 MOV AH, [BP].GPC_ColorF ; Get Foreground Color + 082D EE OUT DX, AL ; Set up Screen Mask + 082E 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 0831 @GPC_NO_LEFT1BITS: + 0831 32 C5 XOR AL, CH ; Invert mask for Background + 0833 74 07 JZ @GPC_NO_LEFT0BITS ; Hey, no need for this + + 0835 8A 66 14 MOV AH, [BP].GPC_ColorB ; Get background Color + 0838 EE OUT DX, AL ; Set up Screen Mask + 0839 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + + 083C @GPC_NO_LEFT0BITS: + 083C 47 INC DI ; Point to next Byte + 083D C1 C3 04 ROL BX, 4 ; Shift 4 bits + + 0840 8B F3 MOV SI, BX ; Make Lookup Pointer + 0842 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + 0845 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 084A 74 07 JZ @GPC_NO_MIDDLE1BITS ; Skip if no pixels to set + + 084C 8A 66 16 MOV AH, [BP].GPC_ColorF ; Get Foreground Color + 084F EE OUT DX, AL ; Set up Screen Mask + 0850 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 0853 @GPC_NO_MIDDLE1BITS: + 0853 34 0F XOR AL, ALL_PLANES ; Invert mask for Background + 0855 74 07 JZ @GPC_NO_MIDDLE0BITS ; Hey, no need for this + + 0857 8A 66 14 MOV AH, [BP].GPC_ColorB ; Get background Color + 085A EE OUT DX, AL ; Set up Screen Mask + 085B 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 085E @GPC_NO_MIDDLE0BITS: + 085E 80 F5 0F XOR CH, ALL_PLANES ; Invert Clip Mask + 0861 80 F9 04 CMP CL, 4 ; Aligned by 4? + 0864 74 23 JZ @GPC_NEXT_LINE ; If so, Exit now.. + + 0866 47 INC DI ; Point to next Byte + 0867 C1 C3 04 ROL BX, 4 ; Shift 4 bits + + 086A 8B F3 MOV SI, BX ; Make Lookup Pointer + 086C 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + 086F 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 0874 74 07 JZ @GPC_NO_RIGHT1BITS ; Skip if No Pixels to set + + 0876 8A 66 16 MOV AH, [BP].GPC_ColorF ; Get Foreground Color + 0879 EE OUT DX, AL ; Set up Screen Mask + 087A 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 087D @GPC_NO_RIGHT1BITS: + + 087D 32 C5 XOR AL, CH ; Invert mask for Background + 087F 74 07 JZ @GPC_NO_RIGHT0BITS ; Hey, no need for this + + 0881 8A 66 14 MOV AH, [BP].GPC_ColorB ; Get background Color + 0884 EE OUT DX, AL ; Set up Screen Mask + 0885 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 0888 @GPC_NO_RIGHT0BITS: + 0888 4F DEC DI ; Adjust for Next Line Advance + + 0889 @GPC_NEXT_LINE: + 0889 03 7E 00 ADD DI, [BP].GPC_Width ; Point to Next Line + 088C 80 F5 0F XOR CH, CHAR_BITS ; Flip the Clip mask back + + 088F FE 4E 02 DEC [BP].GPC_Lines ; Count Down Lines + 0892 74 03 JZ @GPC_EXIT ; Ok... Done! + + 0894 E9 FF78 JMP @GPC_DECODE_CHAR_BYTE ; Again! Hey! + + 0897 @GPC_EXIT: + 0897 83 C4 08 ADD SP, 08 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 089A 5F 1 POP DI ; Restore R1 + 089B 5E 2 POP SI ; Restore R1 + 089C 1F 3 POP DS ; Restore R1 + 089D 5D 4 POP BP ; Restore R1 + 089E CA 000A RET 10 ; Exit and Clean up Stack + + 08A1 GPRINTC ENDP + + + ;========================================== + ;TGPRINTC (CharNum%, Xpos%, Ypos%, ColorF%) + ;========================================== + ; + ; Transparently draws an ASCII Text Character using the + ; currently selected 8x8 font on the active display page. + ; + ; ENTRY: CharNum = ASCII character # to draw + ; Xpos = X position to draw Character at + ; Ypos = Y position of to draw Character at + ; ColorF = Color to draw text character in + ; + ; EXIT: No meaningful values returned + ; + + 001C TGP_STACK STRUC + 0000 0000 TGP_Width DW ? ; Screen Width-1 + 0002 00 00 TGP_Lines DB ?,? ; Scan lines to Decode + 0004 0000 TGP_T_SETS DW ? ; Saved Charset Segment + 0006 0000 TGP_T_SETO DW ? ; Saved Charset Offset + 0008 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0010 00000000 DD ? ; Caller + 0014 00 00 TGP_ColorF DB ?,? ; Text Color + 0016 0000 TGP_Ypos DW ? ; Y Position to Print at + 0018 0000 TGP_Xpos DW ? ; X position to Print at + 001A 00 00 TGP_Char DB ?,? ; Character to Print + TGP_STACK ENDS + + PUBLIC TGPRINTC + + 08A1 TGPRINTC PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 08A1 55 1 PUSH BP ; Save R1 + 08A2 1E 2 PUSH DS ; Save R1 + 08A3 56 3 PUSH SI ; Save R1 + 08A4 57 4 PUSH DI ; Save R1 + 08A5 83 EC 08 SUB SP, 8 ; Allocate WorkSpace on Stack + 08A8 8B EC MOV BP, SP ; Set up Stack Frame + + 08AA C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + + 08AE A1 0000 R MOV AX, SCREEN_WIDTH ; Get Logical Line Width + 08B1 8B D8 MOV BX, AX ; BX = Screen Width + 08B3 4B DEC BX ; = Screen Width-1 + 08B4 89 5E 00 MOV [BP].TGP_Width, BX ; Save for later use + + 08B7 F7 66 16 MUL [BP].TGP_Ypos ; Start of Line = Ypos * Width + 08BA 03 F8 ADD DI, AX ; DI -> Start of Line Ypos + + 08BC 8B 46 18 MOV AX, [BP].TGP_Xpos ; Get Xpos of Character + 08BF 8B C8 MOV CX, AX ; Save Copy of Xpos + 08C1 C1 E8 02 SHR AX, 2 ; Bytes into Line = Xpos/4 + 08C4 03 F8 ADD DI, AX ; DI -> (Xpos, Ypos) + + ;Get Source ADDR of Character Bit Map & Save + + 08C6 8A 46 1A MOV AL, [BP].TGP_Char ; Get Character # + 08C9 A8 80 TEST AL, 080h ; Is Hi Bit Set? + 08CB 74 0C JZ @TGP_LowChar ; Nope, use low char set ptr + + 08CD 24 7F AND AL, 07Fh ; Mask Out Hi Bit + 08CF 8B 1E 0026 R MOV BX, CHARSET_HI ; BX = Char Set Ptr:Offset + 08D3 8B 16 0028 R MOV DX, CHARSET_HI+2 ; DX = Char Set Ptr:Segment + 08D7 EB 08 JMP s @TGP_Set_Char ; Go Setup Character Ptr + + 08D9 @TGP_LowChar: + + 08D9 8B 1E 0022 R MOV BX, CHARSET_LOW ; BX = Char Set Ptr:Offset + 08DD 8B 16 0024 R MOV DX, CHARSET_LOW+2 ; DX = Char Set Ptr:Segment + + 08E1 @TGP_Set_Char: + 08E1 89 56 04 MOV [BP].TGP_T_SETS, DX ; Save Segment on Stack + + 08E4 B4 00 MOV AH, 0 ; Valid #'s are 0..127 + 08E6 C1 E0 03 SHL AX, 3 ; * 8 Bytes Per Bitmap + 08E9 03 D8 ADD BX, AX ; BX = Offset of Selected char + 08EB 89 5E 06 MOV [BP].TGP_T_SETO, BX ; Save Offset on Stack + + 08EE 83 E1 03 AND CX, PLANE_BITS ; Get Plane # + 08F1 B5 0F MOV CH, ALL_PLANES ; Get Initial Plane mask + 08F3 D2 E5 SHL CH, CL ; And shift into position + 08F5 80 E5 0F AND CH, ALL_PLANES ; And mask to lower nibble + + 08F8 B0 04 MOV AL, 04 ; 4-Plane # = # of initial + 08FA 2A C1 SUB AL, CL ; shifts to align bit mask + 08FC 8A C8 MOV CL, AL ; Shift Count for SHL + + ;Get segment of character map + + OUT_8 SC_Index, MAP_MASK ; Setup Plane selections + 08FE BA 03C4 1 MOV DX, SC_Index ; then Select Register + 0901 B0 02 1 MOV AL, MAP_MASK ; then Get Data Value + 0903 EE 1 OUT DX, AL ; Set I/O Register + 0904 42 INC DX ; DX -> SC_Data + + 0905 B0 08 MOV AL, 08 ; 8 Lines to Process + 0907 88 46 02 MOV [BP].TGP_Lines, AL ; Save on Stack + + 090A 8E 5E 04 MOV DS, [BP].TGP_T_SETS ; Point to character set + + 090D @TGP_DECODE_CHAR_BYTE: + + 090D 8B 76 06 MOV SI, [BP].TGP_T_SETO ; Get DS:SI = String + + 0910 8A 3C MOV BH, [SI] ; Get Bit Map + 0912 46 INC SI ; Point to Next Line + 0913 89 76 06 MOV [BP].TGP_T_SETO, SI ; And save new Pointer... + + 0916 8A 66 14 MOV AH, [BP].TGP_ColorF ; Get Foreground Color + + CLR BL ; Clear BL + 0919 32 DB 1 XOR BL, BL ; Set Register = 0 + 091B D3 C3 ROL BX, CL ; BL holds left edge bits + 091D 8B F3 MOV SI, BX ; Use as Table Index + 091F 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + 0922 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 0927 74 04 JZ @TGP_NO_LEFT1BITS ; Skip if No Pixels to set + + 0929 EE OUT DX, AL ; Set up Screen Mask + 092A 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + ;Now Do Middle/Last Band + + 092D @TGP_NO_LEFT1BITS: + + 092D 47 INC DI ; Point to next Byte + 092E C1 C3 04 ROL BX, 4 ; Shift 4 bits + + 0931 8B F3 MOV SI, BX ; Make Lookup Pointer + 0933 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + 0936 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 093B 74 04 JZ @TGP_NO_MIDDLE1BITS ; Skip if no pixels to set + + 093D EE OUT DX, AL ; Set up Screen Mask + 093E 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 0941 @TGP_NO_MIDDLE1BITS: + 0941 80 F5 0F XOR CH, ALL_PLANES ; Invert Clip Mask + 0944 80 F9 04 CMP CL, 4 ; Aligned by 4? + 0947 74 15 JZ @TGP_NEXT_LINE ; If so, Exit now.. + + 0949 47 INC DI ; Point to next Byte + 094A C1 C3 04 ROL BX, 4 ; Shift 4 bits + + 094D 8B F3 MOV SI, BX ; Make Lookup Pointer + 094F 83 E6 0F AND SI, CHAR_BITS ; Get Low Bits + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 11 - 1 + + + 0952 2E: 8A 84 0008 R MOV AL, Char_Plane_Data[SI] ; Get Mask in AL + 0957 74 04 JZ @TGP_NO_RIGHT1BITS ; Skip if No Pixels to set + + 0959 EE OUT DX, AL ; Set up Screen Mask + 095A 26: 88 25 MOV ES:[DI], AH ; Write Foreground color + + 095D @TGP_NO_RIGHT1BITS: + + 095D 4F DEC DI ; Adjust for Next Line Advance + + 095E @TGP_NEXT_LINE: + 095E 03 7E 00 ADD DI, [BP].TGP_Width ; Point to Next Line + 0961 80 F5 0F XOR CH, CHAR_BITS ; Flip the Clip mask back + + 0964 FE 4E 02 DEC [BP].TGP_Lines ; Count Down Lines + 0967 74 02 JZ @TGP_EXIT ; Ok... Done! + + 0969 EB A2 JMP @TGP_DECODE_CHAR_BYTE ; Again! Hey! + + 096B @TGP_EXIT: + 096B 83 C4 08 ADD SP, 08 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 096E 5F 1 POP DI ; Restore R1 + 096F 5E 2 POP SI ; Restore R1 + 0970 1F 3 POP DS ; Restore R1 + 0971 5D 4 POP BP ; Restore R1 + 0972 CA 0008 RET 8 ; Exit and Clean up Stack + + 0975 TGPRINTC ENDP + + + ;=============================================================== + ;PRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) + ;=============================================================== + ; + ; Routine to quickly Print a null terminated ASCII string on the + ; active display page up to a maximum length. + ; + ; ENTRY: String = Far Pointer to ASCII string to print + ; MaxLen = # of characters to print if no null found + ; Xpos = X position to draw Text at + ; Ypos = Y position of to draw Text at + ; ColorF = Color to draw text in + ; ColorB = Color to set background to + ; + ; EXIT: No meaningful values returned + ; + + 001A PS_STACK STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 0000 PS_ColorB DW ? ; Background Color + 000E 0000 PS_ColorF DW ? ; Text Color + 0010 0000 PS_Ypos DW ? ; Y Position to Print at + 0012 0000 PS_Xpos DW ? ; X position to Print at + 0014 0000 PS_Len DW ? ; Maximum Length of string to print + 0016 0000 0000 PS_Text DW ?,? ; Far Ptr to Text String + PS_STACK ENDS + + PUBLIC PRINT_STR + + 0975 PRINT_STR PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0975 55 1 PUSH BP ; Save R1 + 0976 1E 2 PUSH DS ; Save R1 + 0977 56 3 PUSH SI ; Save R1 + 0978 57 4 PUSH DI ; Save R1 + 0979 8B EC MOV BP, SP ; Set up Stack Frame + + 097B @PS_Print_It: + + 097B 8B 4E 14 MOV CX, [BP].PS_Len ; Get Remaining text Length + 097E E3 2F JCXZ @PS_Exit ; Exit when out of text + + 0980 C4 7E 16 LES DI, d [BP].PS_Text ; ES:DI -> Current Char in Text + 0983 26: 8A 05 MOV AL, ES:[DI] ; AL = Text Character + 0986 25 00FF AND AX, 00FFh ; Clear High Word + 0989 74 24 JZ @PS_Exit ; Exit if null character + + 098B FF 4E 14 DEC [BP].PS_Len ; Remaining Text length-- + 098E FF 46 16 INC [BP].PS_Text ; Point to Next text char + + ; Set up Call to GPRINTC + + 0991 50 PUSH AX ; Set Character Parameter + 0992 8B 5E 12 MOV BX, [BP].PS_Xpos ; Get Xpos + 0995 53 PUSH BX ; Set Xpos Parameter + 0996 83 C3 08 ADD BX, 8 ; Advance 1 Char to Right + 0999 89 5E 12 MOV [BP].PS_Xpos, BX ; Save for next time through + + 099C 8B 5E 10 MOV BX, [BP].PS_Ypos ; Get Ypos + 099F 53 PUSH BX ; Set Ypos Parameter + + 09A0 8B 5E 0E MOV BX, [BP].PS_ColorF ; Get Text Color + 09A3 53 PUSH BX ; Set ColorF Parameter + + 09A4 8B 5E 0C MOV BX, [BP].PS_ColorB ; Get Background Color + 09A7 53 PUSH BX ; Set ColorB Parameter + + 09A8 9A ---- 07A3 R CALL f GPRINTC ; Print Character! + 09AD EB CC JMP s @PS_Print_It ; Process next character + + 09AF @PS_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + 09AF 5F 1 POP DI ; Restore R1 + 09B0 5E 2 POP SI ; Restore R1 + 09B1 1F 3 POP DS ; Restore R1 + 09B2 5D 4 POP BP ; Restore R1 + 09B3 CA 000E RET 14 ; Exit and Clean up Stack + + 09B6 PRINT_STR ENDP + + + ;================================================================ + ;TPRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%) + ;================================================================ + ; + ; Routine to quickly transparently Print a null terminated ASCII + ; string on the active display page up to a maximum length. + ; + ; ENTRY: String = Far Pointer to ASCII string to print + ; MaxLen = # of characters to print if no null found + ; Xpos = X position to draw Text at + ; Ypos = Y position of to draw Text at + ; ColorF = Color to draw text in + ; + ; EXIT: No meaningful values returned + ; + + 0018 TPS_STACK STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 0000 TPS_ColorF DW ? ; Text Color + 000E 0000 TPS_Ypos DW ? ; Y Position to Print at + 0010 0000 TPS_Xpos DW ? ; X position to Print at + 0012 0000 TPS_Len DW ? ; Maximum Length of string to print + 0014 0000 0000 TPS_Text DW ?,? ; Far Ptr to Text String + TPS_STACK ENDS + + PUBLIC TPRINT_STR + + 09B6 TPRINT_STR PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 09B6 55 1 PUSH BP ; Save R1 + 09B7 1E 2 PUSH DS ; Save R1 + 09B8 56 3 PUSH SI ; Save R1 + 09B9 57 4 PUSH DI ; Save R1 + 09BA 8B EC MOV BP, SP ; Set up Stack Frame + + 09BC @TPS_Print_It: + + 09BC 8B 4E 12 MOV CX, [BP].TPS_Len ; Get Remaining text Length + 09BF E3 2B JCXZ @TPS_Exit ; Exit when out of text + + 09C1 C4 7E 14 LES DI, d [BP].TPS_Text ; ES:DI -> Current Char in Text + 09C4 26: 8A 05 MOV AL, ES:[DI] ; AL = Text Character + 09C7 25 00FF AND AX, 00FFh ; Clear High Word + 09CA 74 20 JZ @TPS_Exit ; Exit if null character + + 09CC FF 4E 12 DEC [BP].TPS_Len ; Remaining Text length-- + 09CF FF 46 14 INC [BP].TPS_Text ; Point to Next text char + + ; Set up Call to TGPRINTC + + 09D2 50 PUSH AX ; Set Character Parameter + 09D3 8B 5E 10 MOV BX, [BP].TPS_Xpos ; Get Xpos + 09D6 53 PUSH BX ; Set Xpos Parameter + 09D7 83 C3 08 ADD BX, 8 ; Advance 1 Char to Right + 09DA 89 5E 10 MOV [BP].TPS_Xpos, BX ; Save for next time through + + 09DD 8B 5E 0E MOV BX, [BP].TPS_Ypos ; Get Ypos + 09E0 53 PUSH BX ; Set Ypos Parameter + + 09E1 8B 5E 0C MOV BX, [BP].TPS_ColorF ; Get Text Color + 09E4 53 PUSH BX ; Set ColorF Parameter + + 09E5 9A ---- 08A1 R CALL f TGPRINTC ; Print Character! + 09EA EB D0 JMP s @TPS_Print_It ; Process next character + + 09EC @TPS_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + 09EC 5F 1 POP DI ; Restore R1 + 09ED 5E 2 POP SI ; Restore R1 + 09EE 1F 3 POP DS ; Restore R1 + 09EF 5D 4 POP BP ; Restore R1 + 09F0 CA 000C RET 12 ; Exit and Clean up Stack + + 09F3 TPRINT_STR ENDP + + + ;=========================================== + ;SET_DISPLAY_FONT(SEG FontData, FontNumber%) + ;=========================================== + ; + ; Allows the user to specify their own font data for + ; wither the lower or upper 128 characters. + ; + ; ENTRY: FontData = Far Pointer to Font Bitmaps + ; FontNumber = Which half of set this is + ; = 0, Lower 128 characters + ; = 1, Upper 128 characters + ; + ; EXIT: No meaningful values returned + ; + + 000C SDF_STACK STRUC + 0000 0000 DW ? ; BP + 0002 00000000 DD ? ; Caller + 0006 0000 SDF_Which DW ? ; Hi Table/Low Table Flag + 0008 00000000 SDF_Font DD ? ; Far Ptr to Font Table + SDF_STACK ENDS + + PUBLIC SET_DISPLAY_FONT + + 09F3 SET_DISPLAY_FONT PROC FAR + + 09F3 55 PUSH BP ; Preserve Registers + 09F4 8B EC MOV BP, SP ; Set up Stack Frame + + 09F6 C4 7E 08 LES DI, [BP].SDF_Font ; Get Far Ptr to Font + + 09F9 BE 0022 R MOV SI, o CHARSET_LOW ; Assume Lower 128 chars + 09FC F7 46 06 0001 TEST [BP].SDF_Which, 1 ; Font #1 selected? + 0A01 74 03 JZ @SDF_Set_Font ; If not, skip ahead + + 0A03 BE 0026 R MOV SI, o CHARSET_HI ; Ah, really it's 128-255 + + 0A06 @SDF_Set_Font: + 0A06 89 3C MOV [SI], DI ; Set Font Pointer Offset + 0A08 8C 44 02 MOV [SI+2], ES ; Set Font Pointer Segment + + 0A0B 5D POP BP ; Restore Registers + 0A0C CA 0006 RET 6 ; We are Done.. Outa here + + 0A0F SET_DISPLAY_FONT ENDP + + + ; ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== + + ;====================================================== + ;DRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) + ;====================================================== + ; + ; Draws a variable sized Graphics Bitmap such as a + ; picture or an Icon on the current Display Page in + ; Mode X. The Bitmap is stored in a linear byte array + ; corresponding to (0,0) (1,0), (2,0) .. (Width, Height) + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 12 - 1 + + + ; This is the same linear manner as mode 13h graphics. + ; + ; ENTRY: Image = Far Pointer to Bitmap Data + ; Xpos = X position to Place Upper Left pixel at + ; Ypos = Y position to Place Upper Left pixel at + ; Width = Width of the Bitmap in Pixels + ; Height = Height of the Bitmap in Pixels + ; + ; EXIT: No meaningful values returned + ; + + 0022 DB_STACK STRUC + 0000 0000 DB_LineO DW ? ; Offset to Next Line + 0002 0000 DB_PixCount DW ? ; (Minimum) # of Pixels/Line + 0004 0000 DB_Start DW ? ; Addr of Upper Left Pixel + 0006 0000 DB_PixSkew DW ? ; # of bytes to Adjust EOL + 0008 0000 DB_SkewFlag DW ? ; Extra Pix on Plane Flag + 000A 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0012 00000000 DD ? ; Caller + 0016 0000 DB_Height DW ? ; Height of Bitmap in Pixels + 0018 0000 DB_Width DW ? ; Width of Bitmap in Pixels + 001A 0000 DB_Ypos DW ? ; Y position to Draw Bitmap at + 001C 0000 DB_Xpos DW ? ; X position to Draw Bitmap at + 001E 00000000 DB_Image DD ? ; Far Pointer to Graphics Bitmap + DB_STACK ENDS + + PUBLIC DRAW_BITMAP + + 0A0F DRAW_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0A0F 55 1 PUSH BP ; Save R1 + 0A10 1E 2 PUSH DS ; Save R1 + 0A11 56 3 PUSH SI ; Save R1 + 0A12 57 4 PUSH DI ; Save R1 + 0A13 83 EC 0A SUB SP, 10 ; Allocate workspace + 0A16 8B EC MOV BP, SP ; Set up Stack Frame + + 0A18 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + 0A1C FC CLD ; Direction Flag = Forward + + 0A1D 8B 46 1A MOV AX, [BP].DB_Ypos ; Get UL Corner Ypos + 0A20 F7 26 0000 R MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + 0A24 8B 5E 1C MOV BX, [BP].DB_Xpos ; Get UL Corner Xpos + 0A27 8A CB MOV CL, BL ; Save Plane # in CL + 0A29 C1 EB 02 SHR BX, 2 ; Xpos/4 = Offset Into Line + + 0A2C 03 F8 ADD DI, AX ; ES:DI -> Start of Line + 0A2E 03 FB ADD DI, BX ; ES:DI -> Upper Left Pixel + 0A30 89 7E 04 MOV [BP].DB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + 0A33 8B 5E 18 MOV BX, [BP].DB_Width ; Get Width of Image + 0A36 8B D3 MOV DX, BX ; Save Copy in DX + 0A38 C1 EB 02 SHR BX, 2 ; /4 = width in bands + 0A3B A1 0000 R MOV AX, SCREEN_WIDTH ; Get Screen Width + 0A3E 2B C3 SUB AX, BX ; - (Bitmap Width/4) + + 0A40 89 46 00 MOV [BP].DB_LineO, AX ; Save Line Width offset + 0A43 89 5E 02 MOV [BP].DB_PixCount, BX ; Minimum # pix to copy + + 0A46 83 E2 03 AND DX, PLANE_BITS ; Get "partial band" size (0-3) + 0A49 89 56 06 MOV [BP].DB_PixSkew, DX ; Also End of Line Skew + 0A4C 89 56 08 MOV [BP].DB_SkewFlag, DX ; Save as Flag/Count + + 0A4F 83 E1 03 AND CX, PLANE_BITS ; CL = Starting Plane # + 0A52 B8 1102 MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + 0A55 D2 E4 SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + 0A57 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 0A5A EF 1 OUT DX, AX ; Set I/O Register(s) + 0A5B 8A FC MOV BH, AH ; BH = Saved Plane Mask + 0A5D B3 04 MOV BL, 4 ; BL = Planes to Copy + + 0A5F @DB_COPY_PLANE: + + 0A5F C5 76 1E LDS SI, [BP].DB_Image ; DS:SI-> Source Image + 0A62 8B 56 16 MOV DX, [BP].DB_Height ; # of Lines to Copy + 0A65 8B 7E 04 MOV DI, [BP].DB_Start ; ES:DI-> Dest pos + + 0A68 @DB_COPY_LINE: + 0A68 8B 4E 02 MOV CX, [BP].DB_PixCount ; Min # to copy + + 0A6B F6 C1 FC TEST CL, 0FCh ; 16+PixWide? + 0A6E 74 18 JZ @DB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + + 0A70 @DB_COPY_LOOP: + 0A70 A4 MOVSB ; Copy Bitmap Pixel + 0A71 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0A74 A4 MOVSB ; Copy Bitmap Pixel + 0A75 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0A78 A4 MOVSB ; Copy Bitmap Pixel + 0A79 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0A7C A4 MOVSB ; Copy Bitmap Pixel + 0A7D 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + + 0A80 80 E9 04 SUB CL, 4 ; Pixels to Copy=-4 + 0A83 F6 C1 FC TEST CL, 0FCh ; 4+ Pixels Left? + 0A86 75 E8 JNZ @DB_COPY_LOOP ; if so, do another block + + 0A88 @DB_COPY_REMAINDER: + 0A88 E3 07 JCXZ @DB_NEXT_LINE ; Any Pixels left on line + + 0A8A @DB_COPY2: + 0A8A A4 MOVSB ; Copy Bitmap Pixel + 0A8B 83 C6 03 ADD SI,3 ; Skip to Next Byte in same plane + LOOPx CX, @DB_COPY2 ; Pixels to Copy--, Loop until done + 0A8E 49 1 DEC CX ; Counter-- + 0A8F 75 F9 1 JNZ @DB_COPY2 ; Jump if not 0 + + 0A91 @DB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + 0A91 0B 4E 08 OR CX, [BP].DB_SkewFlag ; Get Skew Count + 0A94 74 03 JZ @DB_NEXT2 ; if no partial pixels + + 0A96 A4 MOVSB ; Copy Bitmap Pixel + 0A97 4F DEC DI ; Back up to align + 0A98 4E DEC SI ; Back up to align + + 0A99 @DB_NEXT2: + 0A99 03 76 06 ADD SI, [BP].DB_PixSkew ; Adjust Skew + 0A9C 03 7E 00 ADD DI, [BP].DB_LineO ; Set to Next Display Line + LOOPx DX, @DB_COPY_LINE ; Lines to Copy--, Loop if more + 0A9F 4A 1 DEC DX ; Counter-- + 0AA0 75 C6 1 JNZ @DB_COPY_LINE ; Jump if not 0 + + ; Copy Next Plane.... + + 0AA2 FE CB DEC BL ; Planes to Go-- + 0AA4 74 1B JZ @DB_Exit ; Hey! We are done + + 0AA6 D0 C7 ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + 0AA8 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0AAB 8A C7 1 MOV AL, BH ; then Get Data Value + 0AAD EE 1 OUT DX, AL ; Set I/O Register + + 0AAE 3C 12 CMP AL, 12h ; Carry Set if AL=11h + 0AB0 83 56 04 00 ADC [BP].DB_Start, 0 ; Screen Addr =+Carry + 0AB4 FF 46 1E INC w [BP].DB_Image ; Start @ Next Byte + + 0AB7 83 6E 08 01 SUB [BP].DB_SkewFlag, 1 ; Reduce Planes to Skew + 0ABB 83 56 08 00 ADC [BP].DB_SkewFlag, 0 ; Back to 0 if it was -1 + + 0ABF EB 9E JMP s @DB_COPY_PLANE ; Go Copy the Next Plane + + 0AC1 @DB_Exit: + 0AC1 83 C4 0A ADD SP, 10 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 0AC4 5F 1 POP DI ; Restore R1 + 0AC5 5E 2 POP SI ; Restore R1 + 0AC6 1F 3 POP DS ; Restore R1 + 0AC7 5D 4 POP BP ; Restore R1 + 0AC8 CA 000C RET 12 ; Exit and Clean up Stack + + 0ACB DRAW_BITMAP ENDP + + + ;======================================================= + ;TDRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%) + ;======================================================= + ; + ; Transparently Draws a variable sized Graphics Bitmap + ; such as a picture or an Icon on the current Display Page + ; in Mode X. Pixels with a value of 0 are not drawn, + ; leaving the previous "background" contents intact. + ; + ; The Bitmap format is the same as for the DRAW_BITMAP function. + ; + ; ENTRY: Image = Far Pointer to Bitmap Data + ; Xpos = X position to Place Upper Left pixel at + ; Ypos = Y position to Place Upper Left pixel at + ; Width = Width of the Bitmap in Pixels + ; Height = Height of the Bitmap in Pixels + ; + ; EXIT: No meaningful values returned + ; + + 0022 TB_STACK STRUC + 0000 0000 TB_LineO DW ? ; Offset to Next Line + 0002 0000 TB_PixCount DW ? ; (Minimum) # of Pixels/Line + 0004 0000 TB_Start DW ? ; Addr of Upper Left Pixel + 0006 0000 TB_PixSkew DW ? ; # of bytes to Adjust EOL + 0008 0000 TB_SkewFlag DW ? ; Extra Pix on Plane Flag + 000A 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0012 00000000 DD ? ; Caller + 0016 0000 TB_Height DW ? ; Height of Bitmap in Pixels + 0018 0000 TB_Width DW ? ; Width of Bitmap in Pixels + 001A 0000 TB_Ypos DW ? ; Y position to Draw Bitmap at + 001C 0000 TB_Xpos DW ? ; X position to Draw Bitmap at + 001E 00000000 TB_Image DD ? ; Far Pointer to Graphics Bitmap + TB_STACK ENDS + + PUBLIC TDRAW_BITMAP + + 0ACB TDRAW_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0ACB 55 1 PUSH BP ; Save R1 + 0ACC 1E 2 PUSH DS ; Save R1 + 0ACD 56 3 PUSH SI ; Save R1 + 0ACE 57 4 PUSH DI ; Save R1 + 0ACF 83 EC 0A SUB SP, 10 ; Allocate workspace + 0AD2 8B EC MOV BP, SP ; Set up Stack Frame + + 0AD4 C4 3E 0014 R LES DI, d CURRENT_PAGE ; Point to Active VGA Page + 0AD8 FC CLD ; Direction Flag = Forward + + 0AD9 8B 46 1A MOV AX, [BP].TB_Ypos ; Get UL Corner Ypos + 0ADC F7 26 0000 R MUL SCREEN_WIDTH ; AX = Offset to Line Ypos + + 0AE0 8B 5E 1C MOV BX, [BP].TB_Xpos ; Get UL Corner Xpos + 0AE3 8A CB MOV CL, BL ; Save Plane # in CL + 0AE5 C1 EB 02 SHR BX, 2 ; Xpos/4 = Offset Into Line + + 0AE8 03 F8 ADD DI, AX ; ES:DI -> Start of Line + 0AEA 03 FB ADD DI, BX ; ES:DI -> Upper Left Pixel + 0AEC 89 7E 04 MOV [BP].TB_Start, DI ; Save Starting Addr + + ; Compute line to line offset + + 0AEF 8B 5E 18 MOV BX, [BP].TB_Width ; Get Width of Image + 0AF2 8B D3 MOV DX, BX ; Save Copy in DX + 0AF4 C1 EB 02 SHR BX, 2 ; /4 = width in bands + 0AF7 A1 0000 R MOV AX, SCREEN_WIDTH ; Get Screen Width + 0AFA 2B C3 SUB AX, BX ; - (Bitmap Width/4) + + 0AFC 89 46 00 MOV [BP].TB_LineO, AX ; Save Line Width offset + 0AFF 89 5E 02 MOV [BP].TB_PixCount, BX ; Minimum # pix to copy + + 0B02 83 E2 03 AND DX, PLANE_BITS ; Get "partial band" size (0-3) + 0B05 89 56 06 MOV [BP].TB_PixSkew, DX ; Also End of Line Skew + 0B08 89 56 08 MOV [BP].TB_SkewFlag, DX ; Save as Flag/Count + + 0B0B 83 E1 03 AND CX, PLANE_BITS ; CL = Starting Plane # + 0B0E B8 1102 MOV AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select + 0B11 D2 E4 SHL AH, CL ; Select correct Plane + OUT_16 SC_Index, AX ; Select Plane... + 0B13 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 0B16 EF 1 OUT DX, AX ; Set I/O Register(s) + 0B17 8A FC MOV BH, AH ; BH = Saved Plane Mask + 0B19 B3 04 MOV BL, 4 ; BL = Planes to Copy + + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 13 - 1 + + + 0B1B @TB_COPY_PLANE: + + 0B1B C5 76 1E LDS SI, [BP].TB_Image ; DS:SI-> Source Image + 0B1E 8B 56 16 MOV DX, [BP].TB_Height ; # of Lines to Copy + 0B21 8B 7E 04 MOV DI, [BP].TB_Start ; ES:DI-> Dest pos + + ; Here AH is set with the value to be considered + ; "Transparent". It can be changed! + + 0B24 B4 00 MOV AH, 0 ; Value to Detect 0 + + 0B26 @TB_COPY_LINE: + 0B26 8B 4E 02 MOV CX, [BP].TB_PixCount ; Min # to copy + + 0B29 F6 C1 FC TEST CL, 0FCh ; 16+PixWide? + 0B2C 74 3A JZ @TB_COPY_REMAINDER ; Nope... + + ; Pixel Copy loop has been unrolled to x4 + + 0B2E @TB_COPY_LOOP: + 0B2E AC LODSB ; Get Pixel Value in AL + 0B2F 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0B32 38 E0 CMP AL, AH ; It is "Transparent"? + 0B34 74 03 JE @TB_SKIP_01 ; Skip ahead if so + 0B36 26: 88 05 MOV ES:[DI], AL ; Copy Pixel to VGA screen + + 0B39 @TB_SKIP_01: + 0B39 AC LODSB ; Get Pixel Value in AL + 0B3A 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0B3D 38 E0 CMP AL, AH ; It is "Transparent"? + 0B3F 74 04 JE @TB_SKIP_02 ; Skip ahead if so + 0B41 26: 88 45 01 MOV ES:[DI+1], AL ; Copy Pixel to VGA screen + + 0B45 @TB_SKIP_02: + 0B45 AC LODSB ; Get Pixel Value in AL + 0B46 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0B49 38 E0 CMP AL, AH ; It is "Transparent"? + 0B4B 74 04 JE @TB_SKIP_03 ; Skip ahead if so + 0B4D 26: 88 45 02 MOV ES:[DI+2], AL ; Copy Pixel to VGA screen + + 0B51 @TB_SKIP_03: + 0B51 AC LODSB ; Get Pixel Value in AL + 0B52 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0B55 38 E0 CMP AL, AH ; It is "Transparent"? + 0B57 74 04 JE @TB_SKIP_04 ; Skip ahead if so + 0B59 26: 88 45 03 MOV ES:[DI+3], AL ; Copy Pixel to VGA screen + + 0B5D @TB_SKIP_04: + 0B5D 83 C7 04 ADD DI, 4 ; Adjust Pixel Write Location + 0B60 80 E9 04 SUB CL, 4 ; Pixels to Copy=-4 + 0B63 F6 C1 FC TEST CL, 0FCh ; 4+ Pixels Left? + 0B66 75 C6 JNZ @TB_COPY_LOOP ; if so, do another block + + 0B68 @TB_COPY_REMAINDER: + 0B68 E3 0F JCXZ @TB_NEXT_LINE ; Any Pixels left on line + + 0B6A @TB_COPY2: + 0B6A AC LODSB ; Get Pixel Value in AL + 0B6B 83 C6 03 ADD SI, 3 ; Skip to Next Byte in same plane + 0B6E 38 E0 CMP AL, AH ; It is "Transparent"? + 0B70 74 03 JE @TB_SKIP_05 ; Skip ahead if so + 0B72 26: 88 05 MOV ES:[DI], AL ; Copy Pixel to VGA screen + + 0B75 @TB_SKIP_05: + 0B75 47 INC DI ; Advance Dest Addr + LOOPx CX, @TB_COPY2 ; Pixels to Copy--, Loop until done + 0B76 49 1 DEC CX ; Counter-- + 0B77 75 F1 1 JNZ @TB_COPY2 ; Jump if not 0 + + 0B79 @TB_NEXT_LINE: + + ; any Partial Pixels? (some planes only) + + 0B79 0B 4E 08 OR CX, [BP].TB_SkewFlag ; Get Skew Count + 0B7C 74 09 JZ @TB_NEXT2 ; if no partial pixels + + 0B7E AC LODSB ; Get Pixel Value in AL + 0B7F 4E DEC SI ; Backup to Align + 0B80 38 E0 CMP AL, AH ; It is "Transparent"? + 0B82 74 03 JE @TB_NEXT2 ; Skip ahead if so + 0B84 26: 88 05 MOV ES:[DI], AL ; Copy Pixel to VGA screen + + 0B87 @TB_NEXT2: + 0B87 03 76 06 ADD SI, [BP].TB_PixSkew ; Adjust Skew + 0B8A 03 7E 00 ADD DI, [BP].TB_LineO ; Set to Next Display Line + LOOPx DX, @TB_COPY_LINE ; Lines to Copy--, Loop if More + 0B8D 4A 1 DEC DX ; Counter-- + 0B8E 75 96 1 JNZ @TB_COPY_LINE ; Jump if not 0 + + ;Copy Next Plane.... + + 0B90 FE CB DEC BL ; Planes to Go-- + 0B92 74 1C JZ @TB_Exit ; Hey! We are done + + 0B94 D0 C7 ROL BH, 1 ; Next Plane in line... + OUT_8 SC_Data, BH ; Select Plane + 0B96 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0B99 8A C7 1 MOV AL, BH ; then Get Data Value + 0B9B EE 1 OUT DX, AL ; Set I/O Register + + 0B9C 3C 12 CMP AL, 12h ; Carry Set if AL=11h + 0B9E 83 56 04 00 ADC [BP].TB_Start, 0 ; Screen Addr =+Carry + 0BA2 FF 46 1E INC w [BP].TB_Image ; Start @ Next Byte + + 0BA5 83 6E 08 01 SUB [BP].TB_SkewFlag, 1 ; Reduce Planes to Skew + 0BA9 83 56 08 00 ADC [BP].TB_SkewFlag, 0 ; Back to 0 if it was -1 + + 0BAD E9 FF6B JMP @TB_COPY_PLANE ; Go Copy the next Plane + + 0BB0 @TB_Exit: + 0BB0 83 C4 0A ADD SP, 10 ; Deallocate workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 0BB3 5F 1 POP DI ; Restore R1 + 0BB4 5E 2 POP SI ; Restore R1 + 0BB5 1F 3 POP DS ; Restore R1 + 0BB6 5D 4 POP BP ; Restore R1 + 0BB7 CA 000C RET 12 ; Exit and Clean up Stack + + 0BBA TDRAW_BITMAP ENDP + + + ; ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== + + ;================================== + ;COPY_PAGE (SourcePage%, DestPage%) + ;================================== + ; + ; Duplicate on display page onto another + ; + ; ENTRY: SourcePage = Display Page # to Duplicate + ; DestPage = Display Page # to hold copy + ; + ; EXIT: No meaningful values returned + ; + + 0010 CP_STACK STRUC + 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 0008 00000000 DD ? ; Caller + 000C 0000 CP_DestP DW ? ; Page to hold copied image + 000E 0000 CP_SourceP DW ? ; Page to Make copy from + CP_STACK ENDS + + PUBLIC COPY_PAGE + + 0BBA COPY_PAGE PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0BBA 55 1 PUSH BP ; Save R1 + 0BBB 1E 2 PUSH DS ; Save R1 + 0BBC 56 3 PUSH SI ; Save R1 + 0BBD 57 4 PUSH DI ; Save R1 + 0BBE 8B EC MOV BP, SP ; Set up Stack Frame + 0BC0 FC CLD ; Block Xfer Forwards + + ; Make sure Page #'s are valid + + 0BC1 8B 46 0E MOV AX, [BP].CP_SourceP ; Get Source Page # + 0BC4 3B 06 0004 R CMP AX, LAST_PAGE ; is it > Max Page #? + 0BC8 73 3D JAE @CP_Exit ; if so, abort + + 0BCA 8B 5E 0C MOV BX, [BP].CP_DestP ; Get Destination Page # + 0BCD 3B 1E 0004 R CMP BX, LAST_PAGE ; is it > Max Page #? + 0BD1 73 34 JAE @CP_Exit ; if so, abort + + 0BD3 3B C3 CMP AX, BX ; Pages #'s the same? + 0BD5 74 30 JE @CP_Exit ; if so, abort + + ; Setup DS:SI and ES:DI to Video Pages + + 0BD7 D1 E3 SHL BX, 1 ; Scale index to Word + 0BD9 8B BF 0006 R MOV DI, PAGE_ADDR[BX] ; Offset to Dest Page + + 0BDD 8B D8 MOV BX, AX ; Index to Source page + 0BDF D1 E3 SHL BX, 1 ; Scale index to Word + 0BE1 8B B7 0006 R MOV SI, PAGE_ADDR[BX] ; Offset to Source Page + + 0BE5 8B 0E 000E R MOV CX, PAGE_SIZE ; Get size of Page + 0BE9 A1 0016 R MOV AX, CURRENT_SEGMENT ; Get Video Mem Segment + 0BEC 8E C0 MOV ES, AX ; ES:DI -> Dest Page + 0BEE 8E D8 MOV DS, AX ; DS:SI -> Source Page + + ; Setup VGA registers for Mem to Mem copy + + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + 0BF0 BA 03CE 1 MOV DX, GC_Index ; then Select Register + 0BF3 B8 0008 1 MOV AX, LATCHES_ON ; then Get Data Value + 0BF6 EF 1 OUT DX, AX ; Set I/O Register(s) + OUT_16 SC_Index, ALL_PLANES_ON ; Copy all Planes + 0BF7 BA 03C4 1 MOV DX, SC_Index ; then Select Register + 0BFA B8 0F02 1 MOV AX, ALL_PLANES_ON ; then Get Data Value + 0BFD EF 1 OUT DX, AX ; Set I/O Register(s) + + ; Note.. Do *NOT* use MOVSW or MOVSD - they will + ; Screw with the latches which are 8 bits x 4 + + 0BFE F3/ A4 REP MOVSB ; Copy entire Page! + + ; Reset VGA for normal memory access + + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = off + 0C00 BA 03CE 1 MOV DX, GC_Index ; then Select Register + 0C03 B8 FF08 1 MOV AX, LATCHES_OFF ; then Get Data Value + 0C06 EF 1 OUT DX, AX ; Set I/O Register(s) + + 0C07 @CP_Exit: + POPx DI, SI, DS, BP ; Restore Saved Registers + 0C07 5F 1 POP DI ; Restore R1 + 0C08 5E 2 POP SI ; Restore R1 + 0C09 1F 3 POP DS ; Restore R1 + 0C0A 5D 4 POP BP ; Restore R1 + 0C0B CA 0004 RET 4 ; Exit and Clean up Stack + + 0C0E COPY_PAGE ENDP + + + ;========================================================================== + ;COPY_BITMAP (SourcePage%, X1%, Y1%, X2%, Y2%, DestPage%, DestX1%, DestY1%) + ;========================================================================== + ; + ; Copies a Bitmap Image from one Display Page to Another + ; This Routine is Limited to copying Images with the same + ; Plane Alignment. To Work: (X1 MOD 4) must = (DestX1 MOD 4) + ; Copying an Image to the Same Page is supported, but results + ; may be defined when the when the rectangular areas + ; (X1, Y1) - (X2, Y2) and (DestX1, DestY1) - + ; (DestX1+(X2-X1), DestY1+(Y2-Y1)) overlap... + ; No Paramter checking to done to insure that + ; X2 >= X1 and Y2 >= Y1. Be Careful... + ; + ; ENTRY: SourcePage = Display Page # with Source Image + ; X1 = Upper Left Xpos of Source Image + ; Y1 = Upper Left Ypos of Source Image + ; X2 = Lower Right Xpos of Source Image + ; Y2 = Lower Right Ypos of Source Image + ; DestPage = Display Page # to copy Image to + ; DestX1 = Xpos to Copy UL Corner of Image to + ; DestY1 = Ypos to Copy UL Corner of Image to + ; + ; EXIT: AX = Success Flag: 0 = Failure / -1= Success + ; + + 0020 CB_STACK STRUC + 0000 0000 CB_Height DW ? ; Height of Image in Lines + 0002 0000 CB_Width DW ? ; Width of Image in "bands" + 0004 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP + 0000 + 000C 00000000 DD ? ; Caller + 0010 0000 CB_DestY1 DW ? ; Destination Ypos + 0012 0000 CB_DestX1 DW ? ; Destination Xpos + 0014 0000 CB_DestP DW ? ; Page to Copy Bitmap To + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 14 - 1 + + + 0016 0000 CB_Y2 DW ? ; LR Ypos of Image + 0018 0000 CB_X2 DW ? ; LR Xpos of Image + 001A 0000 CB_Y1 DW ? ; UL Ypos of Image + 001C 0000 CB_X1 DW ? ; UL Xpos of Image + 001E 0000 CB_SourceP DW ? ; Page containing Source Bitmap + CB_STACK ENDS + + PUBLIC COPY_BITMAP + + 0C0E COPY_BITMAP PROC FAR + + PUSHx BP, DS, SI, DI ; Preserve Important Registers + 0C0E 55 1 PUSH BP ; Save R1 + 0C0F 1E 2 PUSH DS ; Save R1 + 0C10 56 3 PUSH SI ; Save R1 + 0C11 57 4 PUSH DI ; Save R1 + 0C12 83 EC 04 SUB SP, 4 ; Allocate WorkSpace on Stack + 0C15 8B EC MOV BP, SP ; Set up Stack Frame + + ; Prep Registers (and keep jumps short!) + + 0C17 8E 06 0016 R MOV ES, CURRENT_SEGMENT ; ES -> VGA Ram + 0C1B FC CLD ; Block Xfer Forwards + + ; Make sure Parameters are valid + + 0C1C 8B 5E 1E MOV BX, [BP].CB_SourceP ; Get Source Page # + 0C1F 3B 1E 0004 R CMP BX, LAST_PAGE ; is it > Max Page #? + 0C23 73 7D JAE @CB_Abort ; if so, abort + + 0C25 8B 4E 14 MOV CX, [BP].CB_DestP ; Get Destination Page # + 0C28 3B 0E 0004 R CMP CX, LAST_PAGE ; is it > Max Page #? + 0C2C 73 74 JAE @CB_Abort ; if so, abort + + 0C2E 8B 46 1C MOV AX, [BP].CB_X1 ; Get Source X1 + 0C31 33 46 12 XOR AX, [BP].CB_DestX1 ; Compare Bits 0-1 + 0C34 83 E0 03 AND AX, PLANE_BITS ; Check Plane Bits + 0C37 75 69 JNZ @CB_Abort ; They should cancel out + + ; Setup for Copy processing + + OUT_8 SC_INDEX, MAP_MASK ; Set up for Plane Select + 0C39 BA 03C4 1 MOV DX, SC_INDEX ; then Select Register + 0C3C B0 02 1 MOV AL, MAP_MASK ; then Get Data Value + 0C3E EE 1 OUT DX, AL ; Set I/O Register + OUT_16 GC_Index, LATCHES_ON ; Data from Latches = on + 0C3F BA 03CE 1 MOV DX, GC_Index ; then Select Register + 0C42 B8 0008 1 MOV AX, LATCHES_ON ; then Get Data Value + 0C45 EF 1 OUT DX, AX ; Set I/O Register(s) + + ; Compute Info About Images, Setup ES:SI & ES:DI + + 0C46 8B 46 16 MOV AX, [BP].CB_Y2 ; Height of Bitmap in lines + 0C49 2B 46 1A SUB AX, [BP].CB_Y1 ; is Y2 - Y1 + 1 + 0C4C 40 INC AX ; (add 1 since were not 0 based) + 0C4D 89 46 00 MOV [BP].CB_Height, AX ; Save on Stack for later use + + 0C50 8B 46 18 MOV AX, [BP].CB_X2 ; Get # of "Bands" of 4 Pixels + 0C53 8B 56 1C MOV DX, [BP].CB_X1 ; the Bitmap Occupies as X2-X1 + 0C56 C1 E8 02 SHR AX, 2 ; Get X2 Band (X2 / 4) + 0C59 C1 EA 02 SHR DX, 2 ; Get X1 Band (X1 / 4) + 0C5C 2B C2 SUB AX, DX ; AX = # of Bands - 1 + 0C5E 40 INC AX ; AX = # of Bands + 0C5F 89 46 02 MOV [BP].CB_Width, AX ; Save on Stack for later use + + 0C62 D1 E3 SHL BX, 1 ; Scale Source Page to Word + 0C64 8B B7 0006 R MOV SI, PAGE_ADDR[BX] ; SI = Offset of Source Page + 0C68 8B 46 1A MOV AX, [BP].CB_Y1 ; Get Source Y1 Line + 0C6B F7 26 0000 R MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + 0C6F 03 F0 ADD SI, AX ; SI = Offset to Line Y1 + 0C71 8B 46 1C MOV AX, [BP].CB_X1 ; Get Source X1 + 0C74 C1 E8 02 SHR AX, 2 ; X1 / 4 = Byte offset + 0C77 03 F0 ADD SI, AX ; SI = Byte Offset to (X1,Y1) + + 0C79 8B D9 MOV BX, CX ; Dest Page Index to BX + 0C7B D1 E3 SHL BX, 1 ; Scale Source Page to Word + 0C7D 8B BF 0006 R MOV DI, PAGE_ADDR[BX] ; DI = Offset of Dest Page + 0C81 8B 46 10 MOV AX, [BP].CB_DestY1 ; Get Dest Y1 Line + 0C84 F7 26 0000 R MUL SCREEN_WIDTH ; AX = Offset to Line Y1 + 0C88 03 F8 ADD DI, AX ; DI = Offset to Line Y1 + 0C8A 8B 46 12 MOV AX, [BP].CB_DestX1 ; Get Dest X1 + 0C8D C1 E8 02 SHR AX, 2 ; X1 / 4 = Byte offset + 0C90 03 F8 ADD DI, AX ; DI = Byte Offset to (D-X1,D-Y1) + + 0C92 8B 4E 02 MOV CX, [BP].CB_Width ; CX = Width of Image (Bands) + 0C95 49 DEC CX ; CX = 1? + 0C96 74 0F JE @CB_Only_One_Band ; 0 Means Image Width of 1 Band + + 0C98 8B 5E 1C MOV BX, [BP].CB_X1 ; Get Source X1 + 0C9B 83 E3 03 AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 00?) + 0C9E 74 70 JZ @CB_Check_Right ; if so, check right alignment + 0CA0 75 41 JNZ @CB_Left_Band ; not aligned? well.. + + 0CA2 @CB_Abort: + CLR AX ; Return False (Failure) + 0CA2 33 C0 1 XOR AX, AX ; Set Register = 0 + 0CA4 E9 00D7 JMP @CB_Exit ; and Finish Up + + ; Copy when Left & Right Clip Masks overlap... + + 0CA7 @CB_Only_One_Band: + 0CA7 8B 5E 1C MOV BX, [BP].CB_X1 ; Get Left Clip Mask + 0CAA 83 E3 03 AND BX, PLANE_BITS ; Mask out Row # + 0CAD 2E: 8A 87 0000 R MOV AL, Left_Clip_Mask[BX] ; Get Left Edge Mask + 0CB2 8B 5E 18 MOV BX, [BP].CB_X2 ; Get Right Clip Mask + 0CB5 83 E3 03 AND BX, PLANE_BITS ; Mask out Row # + 0CB8 2E: 22 87 0004 R AND AL, Right_Clip_Mask[BX] ; Get Right Edge Mask byte + + OUT_8 SC_Data, AL ; Clip For Left & Right Masks + 0CBD BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0CC0 EE 1 OUT DX, AL ; Set I/O Register + + 0CC1 8B 4E 00 MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + 0CC4 8B 16 0000 R MOV DX, SCREEN_WIDTH ; DX = Width of Screen + CLR BX ; BX = Offset into Image + 0CC8 33 DB 1 XOR BX, BX ; Set Register = 0 + + 0CCA @CB_One_Loop: + 0CCA 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0CCD 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0CD0 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_One_Done ; Exit Loop if Finished + 0CD2 49 1 DEC CX ; Counter-- + 0CD3 74 0B 1 JZ @CB_One_Done ; Jump if 0 + + 0CD5 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0CD8 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0CDB 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_One_Loop ; Loop until Finished + 0CDD 49 1 DEC CX ; Counter-- + 0CDE 75 EA 1 JNZ @CB_One_Loop ; Jump if not 0 + + 0CE0 @CB_One_Done: + 0CE0 E9 0094 JMP @CB_Finish ; Outa Here! + + ; Copy Left Edge of Bitmap + + 0CE3 @CB_Left_Band: + + OUT_8 SC_Data, Left_Clip_Mask[BX] ; Set Left Edge Plane Mask + 0CE3 BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0CE6 2E: 8A 87 0000 R 1 MOV AL, Left_Clip_Mask[BX] ; then Get Data Value + 0CEB EE 1 OUT DX, AL ; Set I/O Register + + 0CEC 8B 4E 00 MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + 0CEF 8B 16 0000 R MOV DX, SCREEN_WIDTH ; DX = Width of Screen + CLR BX ; BX = Offset into Image + 0CF3 33 DB 1 XOR BX, BX ; Set Register = 0 + + 0CF5 @CB_Left_Loop: + 0CF5 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0CF8 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0CFB 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Left_Done ; Exit Loop if Finished + 0CFD 49 1 DEC CX ; Counter-- + 0CFE 74 0B 1 JZ @CB_Left_Done ; Jump if 0 + + 0D00 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0D03 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0D06 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Left_Loop ; Loop until Finished + 0D08 49 1 DEC CX ; Counter-- + 0D09 75 EA 1 JNZ @CB_Left_Loop ; Jump if not 0 + + 0D0B @CB_Left_Done: + 0D0B 47 INC DI ; Move Dest Over 1 band + 0D0C 46 INC SI ; Move Source Over 1 band + 0D0D FF 4E 02 DEC [BP].CB_Width ; Band Width-- + + ; Determine if Right Edge of Bitmap needs special copy + + 0D10 @CB_Check_Right: + 0D10 8B 5E 18 MOV BX, [BP].CB_X2 ; Get Source X2 + 0D13 83 E3 03 AND BX, PLANE_BITS ; Aligned? (bits 0-1 = 11?) + 0D16 80 FB 03 CMP BL, 03h ; Plane = 3? + 0D19 74 2C JE @CB_Copy_Middle ; Copy the Middle then! + + ; Copy Right Edge of Bitmap + + 0D1B @CB_Right_Band: + + OUT_8 SC_Data, Right_Clip_Mask[BX] ; Set Right Edge Plane Mask + 0D1B BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0D1E 2E: 8A 87 0004 R 1 MOV AL, Right_Clip_Mask[BX] ; then Get Data Value + 0D23 EE 1 OUT DX, AL ; Set I/O Register + + 0D24 FF 4E 02 DEC [BP].CB_Width ; Band Width-- + 0D27 8B 4E 00 MOV CX, [BP].CB_Height ; CX = # of Lines to Copy + 0D2A 8B 16 0000 R MOV DX, SCREEN_WIDTH ; DX = Width of Screen + 0D2E 8B 5E 02 MOV BX, [BP].CB_Width ; BX = Offset to Right Edge + + 0D31 @CB_Right_Loop: + 0D31 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0D34 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0D37 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPjz CX, @CB_Right_Done ; Exit Loop if Finished + 0D39 49 1 DEC CX ; Counter-- + 0D3A 74 0B 1 JZ @CB_Right_Done ; Jump if 0 + + 0D3C 26: 8A 00 MOV AL, ES:[SI+BX] ; Load Latches + 0D3F 26: 88 01 MOV ES:[DI+BX], AL ; Unload Latches + 0D42 03 DA ADD BX, DX ; Advance Offset to Next Line + LOOPx CX, @CB_Right_Loop ; Loop until Finished + 0D44 49 1 DEC CX ; Counter-- + 0D45 75 EA 1 JNZ @CB_Right_Loop ; Jump if not 0 + + 0D47 @CB_Right_Done: + + ; Copy the Main Block of the Bitmap + + 0D47 @CB_Copy_Middle: + + 0D47 8B 4E 02 MOV CX, [BP].CB_Width ; Get Width Remaining + 0D4A E3 2B JCXZ @CB_Finish ; Exit if Done + + OUT_8 SC_Data, ALL_PLANES ; Copy all Planes + 0D4C BA 03C5 1 MOV DX, SC_Data ; then Select Register + 0D4F B0 0F 1 MOV AL, ALL_PLANES ; then Get Data Value + 0D51 EE 1 OUT DX, AL ; Set I/O Register + + 0D52 8B 16 0000 R MOV DX, SCREEN_WIDTH ; Get Width of Screen minus + 0D56 2B D1 SUB DX, CX ; Image width (for Adjustment) + 0D58 8B 46 00 MOV AX, [BP].CB_Height ; AX = # of Lines to Copy + 0D5B 8B D9 MOV BX, CX ; BX = Quick REP reload count + 0D5D 8C C1 MOV CX, ES ; Move VGA Segment + 0D5F 8E D9 MOV DS, CX ; Into DS + + ; Actual Copy Loop. REP MOVSB does the work + + 0D61 @CB_Middle_Copy: + 0D61 8B CB MOV CX, BX ; Recharge Rep Count + 0D63 F3/ A4 REP MOVSB ; Move Bands + LOOPjz AX, @CB_Finish ; Exit Loop if Finished + 0D65 48 1 DEC AX ; Counter-- + 0D66 74 0F 1 JZ @CB_Finish ; Jump if 0 + + 0D68 03 F2 ADD SI, DX ; Adjust DS:SI to Next Line + 0D6A 03 FA ADD DI, DX ; Adjust ES:DI to Next Line + + 0D6C 8B CB MOV CX, BX ; Recharge Rep Count + 0D6E F3/ A4 REP MOVSB ; Move Bands + + 0D70 03 F2 ADD SI, DX ; Adjust DS:SI to Next Line + 0D72 03 FA ADD DI, DX ; Adjust ES:DI to Next Line + LOOPx AX, @CB_Middle_Copy ; Copy Lines until Done + 0D74 48 1 DEC AX ; Counter-- + 0D75 75 EA 1 JNZ @CB_Middle_Copy ; Jump if not 0 + + 0D77 @CB_Finish: + OUT_16 GC_Index, LATCHES_OFF ; Data from Latches = on + 0D77 BA 03CE 1 MOV DX, GC_Index ; then Select Register + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Page 15 - 1 + + + 0D7A B8 FF08 1 MOV AX, LATCHES_OFF ; then Get Data Value + 0D7D EF 1 OUT DX, AX ; Set I/O Register(s) + + 0D7E @CB_Exit: + 0D7E 83 C4 04 ADD SP, 04 ; Deallocate stack workspace + POPx DI, SI, DS, BP ; Restore Saved Registers + 0D81 5F 1 POP DI ; Restore R1 + 0D82 5E 2 POP SI ; Restore R1 + 0D83 1F 3 POP DS ; Restore R1 + 0D84 5D 4 POP BP ; Restore R1 + 0D85 CA 0010 RET 16 ; Exit and Clean up Stack + + 0D88 COPY_BITMAP ENDP + + END ; End of Code Segment + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Symbols 16 - 1 + + + + +Macros: + + N a m e Type + +CLR . . . . . . . . . . . . . . Proc +LOOPjz . . . . . . . . . . . . . Proc +LOOPx . . . . . . . . . . . . . Proc +OUT_16 . . . . . . . . . . . . . Proc +OUT_8 . . . . . . . . . . . . . Proc +POPx . . . . . . . . . . . . . . Proc +PUSHx . . . . . . . . . . . . . Proc + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Symbols 17 - 1 + + + + +Structures and Unions: + + N a m e Size + Offset Type + +CB_STACK . . . . . . . . . . . . 0020 + CB_Height . . . . . . . . . . 0000 Word + CB_Width . . . . . . . . . . . 0002 Word + CB_DestY1 . . . . . . . . . . 0010 Word + CB_DestX1 . . . . . . . . . . 0012 Word + CB_DestP . . . . . . . . . . . 0014 Word + CB_Y2 . . . . . . . . . . . . 0016 Word + CB_X2 . . . . . . . . . . . . 0018 Word + CB_Y1 . . . . . . . . . . . . 001A Word + CB_X1 . . . . . . . . . . . . 001C Word + CB_SourceP . . . . . . . . . . 001E Word +CP_STACK . . . . . . . . . . . . 0010 + CP_DestP . . . . . . . . . . . 000C Word + CP_SourceP . . . . . . . . . . 000E Word +CVS_STACK . . . . . . . . . . . 000A + CVS_COLOR . . . . . . . . . . 0008 Byte +DB_STACK . . . . . . . . . . . . 0022 + DB_LineO . . . . . . . . . . . 0000 Word + DB_PixCount . . . . . . . . . 0002 Word + DB_Start . . . . . . . . . . . 0004 Word + DB_PixSkew . . . . . . . . . . 0006 Word + DB_SkewFlag . . . . . . . . . 0008 Word + DB_Height . . . . . . . . . . 0016 Word + DB_Width . . . . . . . . . . . 0018 Word + DB_Ypos . . . . . . . . . . . 001A Word + DB_Xpos . . . . . . . . . . . 001C Word + DB_Image . . . . . . . . . . . 001E DWord +DL_STACK . . . . . . . . . . . . 0014 + DL_ColorF . . . . . . . . . . 000A Byte + DL_Ypos2 . . . . . . . . . . . 000C Word + DL_Xpos2 . . . . . . . . . . . 000E Word + DL_Ypos1 . . . . . . . . . . . 0010 Word + DL_Xpos1 . . . . . . . . . . . 0012 Word +FB_STACK . . . . . . . . . . . . 0016 + FB_Color . . . . . . . . . . . 000C Byte + FB_Ypos2 . . . . . . . . . . . 000E Word + FB_Xpos2 . . . . . . . . . . . 0010 Word + FB_Ypos1 . . . . . . . . . . . 0012 Word + FB_Xpos1 . . . . . . . . . . . 0014 Word +GDR_STACK . . . . . . . . . . . 000E + GDR_Blue . . . . . . . . . . . 0006 Word + GDR_Green . . . . . . . . . . 0008 Word + GDR_Red . . . . . . . . . . . 000A Word + GDR_Register . . . . . . . . . 000C Byte +GPC_STACK . . . . . . . . . . . 001E + GPC_Width . . . . . . . . . . 0000 Word + GPC_Lines . . . . . . . . . . 0002 Byte + GPC_T_SETS . . . . . . . . . . 0004 Word + GPC_T_SETO . . . . . . . . . . 0006 Word + GPC_ColorB . . . . . . . . . . 0014 Byte + GPC_ColorF . . . . . . . . . . 0016 Byte + GPC_Ypos . . . . . . . . . . . 0018 Word + GPC_Xpos . . . . . . . . . . . 001A Word + GPC_Char . . . . . . . . . . . 001C Byte +LDR_STACK . . . . . . . . . . . 0014 + LDR_Sync . . . . . . . . . . . 000A Word + LDR_EndReg . . . . . . . . . . 000C Byte + LDR_StartReg . . . . . . . . . 000E Byte + LDR_PalData . . . . . . . . . 0010 DWord +Mode_Data_Table . . . . . . . . 000C + M_MiscR . . . . . . . . . . . 0000 Byte + M_Pages . . . . . . . . . . . 0001 Byte + M_XSize . . . . . . . . . . . 0002 Word + M_YSize . . . . . . . . . . . 0004 Word + M_XMax . . . . . . . . . . . . 0006 Word + M_YMax . . . . . . . . . . . . 0008 Word + M_CRTC . . . . . . . . . . . . 000A Word +PS_STACK . . . . . . . . . . . . 001A + PS_ColorB . . . . . . . . . . 000C Word + PS_ColorF . . . . . . . . . . 000E Word + PS_Ypos . . . . . . . . . . . 0010 Word + PS_Xpos . . . . . . . . . . . 0012 Word + PS_Len . . . . . . . . . . . . 0014 Word + PS_Text . . . . . . . . . . . 0016 Word +RDR_STACK . . . . . . . . . . . 0012 + RDR_EndReg . . . . . . . . . . 000A Byte + RDR_StartReg . . . . . . . . . 000C Byte + RDR_PalData . . . . . . . . . 000E DWord +RP_STACK . . . . . . . . . . . . 000C + RP_Ypos . . . . . . . . . . . 0008 Word + RP_Xpos . . . . . . . . . . . 000A Word +SAP_STACK . . . . . . . . . . . 0008 + SAP_Page . . . . . . . . . . . 0006 Word +SDF_STACK . . . . . . . . . . . 000C + SDF_Which . . . . . . . . . . 0006 Word + SDF_Font . . . . . . . . . . . 0008 DWord +SDP_STACK . . . . . . . . . . . 0008 + SDP_Page . . . . . . . . . . . 0006 Word +SDR_STACK . . . . . . . . . . . 000E + SDR_Blue . . . . . . . . . . . 0006 Byte + SDR_Green . . . . . . . . . . 0008 Byte + SDR_Red . . . . . . . . . . . 000A Byte + SDR_Register . . . . . . . . . 000C Byte +SM_STACK . . . . . . . . . . . . 000A + SM_Mode . . . . . . . . . . . 0008 Word +SP_STACK . . . . . . . . . . . . 000E + SETP_Color . . . . . . . . . . 0008 Byte + SETP_Ypos . . . . . . . . . . 000A Word + SETP_Xpos . . . . . . . . . . 000C Word +SVM_STACK . . . . . . . . . . . 0016 + SVM_Table . . . . . . . . . . 0000 Word + SVM_Pages . . . . . . . . . . 000E Word + SVM_Ysize . . . . . . . . . . 0010 Word + SVM_Xsize . . . . . . . . . . 0012 Word + SVM_Mode . . . . . . . . . . . 0014 Word +SW_STACK . . . . . . . . . . . . 000C + SW_Ypos . . . . . . . . . . . 0006 Word + SW_Xpos . . . . . . . . . . . 0008 Word + SW_Page . . . . . . . . . . . 000A Word +TB_STACK . . . . . . . . . . . . 0022 + TB_LineO . . . . . . . . . . . 0000 Word + TB_PixCount . . . . . . . . . 0002 Word + TB_Start . . . . . . . . . . . 0004 Word + TB_PixSkew . . . . . . . . . . 0006 Word + TB_SkewFlag . . . . . . . . . 0008 Word + TB_Height . . . . . . . . . . 0016 Word + TB_Width . . . . . . . . . . . 0018 Word + TB_Ypos . . . . . . . . . . . 001A Word + TB_Xpos . . . . . . . . . . . 001C Word + TB_Image . . . . . . . . . . . 001E DWord +TGP_STACK . . . . . . . . . . . 001C + TGP_Width . . . . . . . . . . 0000 Word + TGP_Lines . . . . . . . . . . 0002 Byte + TGP_T_SETS . . . . . . . . . . 0004 Word + TGP_T_SETO . . . . . . . . . . 0006 Word + TGP_ColorF . . . . . . . . . . 0014 Byte + TGP_Ypos . . . . . . . . . . . 0016 Word + TGP_Xpos . . . . . . . . . . . 0018 Word + TGP_Char . . . . . . . . . . . 001A Byte +TPS_STACK . . . . . . . . . . . 0018 + TPS_ColorF . . . . . . . . . . 000C Word + TPS_Ypos . . . . . . . . . . . 000E Word + TPS_Xpos . . . . . . . . . . . 0010 Word + TPS_Len . . . . . . . . . . . 0012 Word + TPS_Text . . . . . . . . . . . 0014 Word + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Symbols 18 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +DGROUP . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 16 Bit 0000 Word Public 'DATA' +_BSS . . . . . . . . . . . . . . 16 Bit 002A Word Public 'BSS' +MODEX_TEXT . . . . . . . . . . . 16 Bit 0D88 Word Public 'CODE' + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Symbols 19 - 1 + + + + +Procedures, parameters and locals: + + N a m e Type Value Attr + +CLEAR_VGA_SCREEN . . . . . . . . P Far 0280 MODEX_TEXT Length= 0022 Public +COPY_BITMAP . . . . . . . . . . P Far 0C0E MODEX_TEXT Length= 017E Public +COPY_PAGE . . . . . . . . . . . P Far 0BBA MODEX_TEXT Length= 0054 Public +DRAW_BITMAP . . . . . . . . . . P Far 0A0F MODEX_TEXT Length= 00BC Public +DRAW_LINE . . . . . . . . . . . P Far 040B MODEX_TEXT Length= 02A7 Public +FILL_BLOCK . . . . . . . . . . . P Far 0300 MODEX_TEXT Length= 010B Public +GET_ACTIVE_PAGE . . . . . . . . P Far 06E5 MODEX_TEXT Length= 0004 Public +GET_DAC_REGISTER . . . . . . . . P Far 0641 MODEX_TEXT Length= 0025 Public +GET_DISPLAY_PAGE . . . . . . . . P Far 0724 MODEX_TEXT Length= 0004 Public +GET_X_OFFSET . . . . . . . . . . P Far 078D MODEX_TEXT Length= 0004 Public +GET_Y_OFFSET . . . . . . . . . . P Far 0791 MODEX_TEXT Length= 0004 Public +GPRINTC . . . . . . . . . . . . P Far 07A3 MODEX_TEXT Length= 00FE Public +LOAD_DAC_REGISTERS . . . . . . . P Far 0666 MODEX_TEXT Length= 0037 Public +PRINT_STR . . . . . . . . . . . P Far 0975 MODEX_TEXT Length= 0041 Public +READ_DAC_REGISTERS . . . . . . . P Far 069D MODEX_TEXT Length= 002B Public +READ_POINT . . . . . . . . . . . P Far 02D2 MODEX_TEXT Length= 002E Public +SET_ACTIVE_PAGE . . . . . . . . P Far 06C8 MODEX_TEXT Length= 001D Public +SET_DAC_REGISTER . . . . . . . . P Far 0624 MODEX_TEXT Length= 001D Public +SET_DISPLAY_FONT . . . . . . . . P Far 09F3 MODEX_TEXT Length= 001C Public +SET_DISPLAY_PAGE . . . . . . . . P Far 06E9 MODEX_TEXT Length= 003B Public +SET_MODEX . . . . . . . . . . . P Far 0251 MODEX_TEXT Length= 002F Public +SET_POINT . . . . . . . . . . . P Far 02A2 MODEX_TEXT Length= 0030 Public +SET_VGA_MODEX . . . . . . . . . P Far 0104 MODEX_TEXT Length= 014D Public +SET_WINDOW . . . . . . . . . . . P Far 0728 MODEX_TEXT Length= 0065 Public +SYNC_DISPLAY . . . . . . . . . . P Far 0795 MODEX_TEXT Length= 000E Public +TDRAW_BITMAP . . . . . . . . . . P Far 0ACB MODEX_TEXT Length= 00EF Public +TGPRINTC . . . . . . . . . . . . P Far 08A1 MODEX_TEXT Length= 00D4 Public +TPRINT_STR . . . . . . . . . . . P Far 09B6 MODEX_TEXT Length= 003D Public + Microsoft (R) Macro Assembler Version 6.11 07/02/14 15:18:33 +modex.asm Symbols 20 - 1 + + + + +Symbols: + + N a m e Type Value Attr + +?x3 . . . . . . . . . . . . . . Text ?,?,? +?x4 . . . . . . . . . . . . . . Text ?,?,?,? +@CB_Abort . . . . . . . . . . . L Near 0CA2 MODEX_TEXT +@CB_Check_Right . . . . . . . . L Near 0D10 MODEX_TEXT +@CB_Copy_Middle . . . . . . . . L Near 0D47 MODEX_TEXT +@CB_Exit . . . . . . . . . . . . L Near 0D7E MODEX_TEXT +@CB_Finish . . . . . . . . . . . L Near 0D77 MODEX_TEXT +@CB_Left_Band . . . . . . . . . L Near 0CE3 MODEX_TEXT +@CB_Left_Done . . . . . . . . . L Near 0D0B MODEX_TEXT +@CB_Left_Loop . . . . . . . . . L Near 0CF5 MODEX_TEXT +@CB_Middle_Copy . . . . . . . . L Near 0D61 MODEX_TEXT +@CB_One_Done . . . . . . . . . . L Near 0CE0 MODEX_TEXT +@CB_One_Loop . . . . . . . . . . L Near 0CCA MODEX_TEXT +@CB_Only_One_Band . . . . . . . L Near 0CA7 MODEX_TEXT +@CB_Right_Band . . . . . . . . . L Near 0D1B MODEX_TEXT +@CB_Right_Done . . . . . . . . . L Near 0D47 MODEX_TEXT +@CB_Right_Loop . . . . . . . . . L Near 0D31 MODEX_TEXT +@CP_Exit . . . . . . . . . . . . L Near 0C07 MODEX_TEXT +@CodeSize . . . . . . . . . . . Number 0001h +@DB_COPY2 . . . . . . . . . . . L Near 0A8A MODEX_TEXT +@DB_COPY_LINE . . . . . . . . . L Near 0A68 MODEX_TEXT +@DB_COPY_LOOP . . . . . . . . . L Near 0A70 MODEX_TEXT +@DB_COPY_PLANE . . . . . . . . . L Near 0A5F MODEX_TEXT +@DB_COPY_REMAINDER . . . . . . . L Near 0A88 MODEX_TEXT +@DB_Exit . . . . . . . . . . . . L Near 0AC1 MODEX_TEXT +@DB_NEXT2 . . . . . . . . . . . L Near 0A99 MODEX_TEXT +@DB_NEXT_LINE . . . . . . . . . L Near 0A91 MODEX_TEXT +@DL_BREZHAM . . . . . . . . . . L Near 04C7 MODEX_TEXT +@DL_DeltaYOK2 . . . . . . . . . L Near 0515 MODEX_TEXT +@DL_DeltaYOK . . . . . . . . . . L Near 04DC MODEX_TEXT +@DL_DrawLeft . . . . . . . . . . L Near 051F MODEX_TEXT +@DL_DrawRight . . . . . . . . . L Near 05A3 MODEX_TEXT +@DL_EXIT2 . . . . . . . . . . . L Near 061E MODEX_TEXT +@DL_EXIT . . . . . . . . . . . . L Near 04C4 MODEX_TEXT +@DL_HORZ . . . . . . . . . . . . L Near 0433 MODEX_TEXT +@DL_LONGLN . . . . . . . . . . . L Near 0461 MODEX_TEXT +@DL_NOSWAP1 . . . . . . . . . . L Near 0428 MODEX_TEXT +@DL_NOSWAP2 . . . . . . . . . . L Near 048C MODEX_TEXT +@DL_SLLExit . . . . . . . . . . L Near 0563 MODEX_TEXT +@DL_SLLL2nc . . . . . . . . . . L Near 0543 MODEX_TEXT +@DL_SLLL3nc . . . . . . . . . . L Near 0558 MODEX_TEXT +@DL_SLLLoop . . . . . . . . . . L Near 0537 MODEX_TEXT +@DL_SLR2nc . . . . . . . . . . . L Near 05C5 MODEX_TEXT +@DL_SLR3nc . . . . . . . . . . . L Near 05D9 MODEX_TEXT +@DL_SLRExit . . . . . . . . . . L Near 05E3 MODEX_TEXT +@DL_SLRLoop . . . . . . . . . . L Near 05B9 MODEX_TEXT +@DL_STLExit . . . . . . . . . . L Near 05A1 MODEX_TEXT +@DL_STLLoop . . . . . . . . . . L Near 0575 MODEX_TEXT +@DL_STLnc2 . . . . . . . . . . . L Near 0588 MODEX_TEXT +@DL_STLnc3 . . . . . . . . . . . L Near 059D MODEX_TEXT +@DL_ShallowLeft . . . . . . . . L Near 0525 MODEX_TEXT +@DL_ShallowRight . . . . . . . . L Near 05A7 MODEX_TEXT +@DL_SteepLeft . . . . . . . . . L Near 0566 MODEX_TEXT +@DL_SteepRight . . . . . . . . . L Near 05E5 MODEX_TEXT +@DL_VLINE . . . . . . . . . . . L Near 0481 MODEX_TEXT +@DL_VLoop . . . . . . . . . . . L Near 04B4 MODEX_TEXT +@DL_XRSEG . . . . . . . . . . . L Near 0479 MODEX_TEXT +@DP_WAIT0 . . . . . . . . . . . L Near 0706 MODEX_TEXT +@DP_WAIT1 . . . . . . . . . . . L Near 071B MODEX_TEXT +@DataSize . . . . . . . . . . . Number 0000h +@FB_EXIT . . . . . . . . . . . . L Near 0404 MODEX_TEXT +@FB_LEFT_CONT . . . . . . . . . L Near 037A MODEX_TEXT +@FB_LEFT_LOOP . . . . . . . . . L Near 036A MODEX_TEXT +@FB_L_PLANE_FLUSH . . . . . . . L Near 037C MODEX_TEXT +@FB_MIDDLE_LOOP . . . . . . . . L Near 03C7 MODEX_TEXT +@FB_NORMAL . . . . . . . . . . . L Near 034C MODEX_TEXT +@FB_NOSWAP1 . . . . . . . . . . L Near 031F MODEX_TEXT +@FB_NOSWAP2 . . . . . . . . . . L Near 0339 MODEX_TEXT +@FB_ONE_BAND_ONLY . . . . . . . L Near 03D2 MODEX_TEXT +@FB_ONE_LOOP . . . . . . . . . . L Near 03F4 MODEX_TEXT +@FB_RIGHT_CONT . . . . . . . . . L Near 03B0 MODEX_TEXT +@FB_RIGHT_LOOP . . . . . . . . . L Near 03A0 MODEX_TEXT +@FB_RIGHT . . . . . . . . . . . L Near 037D MODEX_TEXT +@FB_R_EDGE_FLUSH . . . . . . . . L Near 03B3 MODEX_TEXT +@GPC_DECODE_CHAR_BYTE . . . . . L Near 080F MODEX_TEXT +@GPC_EXIT . . . . . . . . . . . L Near 0897 MODEX_TEXT +@GPC_LowChar . . . . . . . . . . L Near 07DB MODEX_TEXT +@GPC_NEXT_LINE . . . . . . . . . L Near 0889 MODEX_TEXT +@GPC_NO_LEFT0BITS . . . . . . . L Near 083C MODEX_TEXT +@GPC_NO_LEFT1BITS . . . . . . . L Near 0831 MODEX_TEXT +@GPC_NO_MIDDLE0BITS . . . . . . L Near 085E MODEX_TEXT +@GPC_NO_MIDDLE1BITS . . . . . . L Near 0853 MODEX_TEXT +@GPC_NO_RIGHT0BITS . . . . . . . L Near 0888 MODEX_TEXT +@GPC_NO_RIGHT1BITS . . . . . . . L Near 087D MODEX_TEXT +@GPC_Set_Char . . . . . . . . . L Near 07E3 MODEX_TEXT +@Interface . . . . . . . . . . . Number 0000h +@LDR_Load . . . . . . . . . . . L Near 0677 MODEX_TEXT +@Model . . . . . . . . . . . . . Number 0004h +@PS_Exit . . . . . . . . . . . . L Near 09AF MODEX_TEXT +@PS_Print_It . . . . . . . . . . L Near 097B MODEX_TEXT +@SAP_Exit . . . . . . . . . . . L Near 06E1 MODEX_TEXT +@SDF_Set_Font . . . . . . . . . L Near 0A06 MODEX_TEXT +@SDP_Exit . . . . . . . . . . . L Near 0720 MODEX_TEXT +@SD_WAIT0 . . . . . . . . . . . L Near 0798 MODEX_TEXT +@SD_WAIT1 . . . . . . . . . . . L Near 079D MODEX_TEXT +@SMX_Exit . . . . . . . . . . . L Near 027B MODEX_TEXT +@STRLoop . . . . . . . . . . . . L Near 05F4 MODEX_TEXT +@STRnc2 . . . . . . . . . . . . L Near 0606 MODEX_TEXT +@STRnc3 . . . . . . . . . . . . L Near 061A MODEX_TEXT +@SVM_BadModeSetup . . . . . . . L Near 015C MODEX_TEXT +@SVM_Continue . . . . . . . . . L Near 0161 MODEX_TEXT +@SVM_EXIT . . . . . . . . . . . L Near 0247 MODEX_TEXT +@SVM_Set_Data . . . . . . . . . L Near 01AA MODEX_TEXT +@SVM_Set_Pages . . . . . . . . . L Near 0207 MODEX_TEXT +@SVM_Setup_CRTC . . . . . . . . L Near 019D MODEX_TEXT +@SVM_Setup_Table . . . . . . . . L Near 0193 MODEX_TEXT +@SW_Exit . . . . . . . . . . . . L Near 0789 MODEX_TEXT +@SW_WAIT0 . . . . . . . . . . . L Near 0761 MODEX_TEXT +@SW_WAIT1 . . . . . . . . . . . L Near 0776 MODEX_TEXT +@TB_COPY2 . . . . . . . . . . . L Near 0B6A MODEX_TEXT +@TB_COPY_LINE . . . . . . . . . L Near 0B26 MODEX_TEXT +@TB_COPY_LOOP . . . . . . . . . L Near 0B2E MODEX_TEXT +@TB_COPY_PLANE . . . . . . . . . L Near 0B1B MODEX_TEXT +@TB_COPY_REMAINDER . . . . . . . L Near 0B68 MODEX_TEXT +@TB_Exit . . . . . . . . . . . . L Near 0BB0 MODEX_TEXT +@TB_NEXT2 . . . . . . . . . . . L Near 0B87 MODEX_TEXT +@TB_NEXT_LINE . . . . . . . . . L Near 0B79 MODEX_TEXT +@TB_SKIP_01 . . . . . . . . . . L Near 0B39 MODEX_TEXT +@TB_SKIP_02 . . . . . . . . . . L Near 0B45 MODEX_TEXT +@TB_SKIP_03 . . . . . . . . . . L Near 0B51 MODEX_TEXT +@TB_SKIP_04 . . . . . . . . . . L Near 0B5D MODEX_TEXT +@TB_SKIP_05 . . . . . . . . . . L Near 0B75 MODEX_TEXT +@TGP_DECODE_CHAR_BYTE . . . . . L Near 090D MODEX_TEXT +@TGP_EXIT . . . . . . . . . . . L Near 096B MODEX_TEXT +@TGP_LowChar . . . . . . . . . . L Near 08D9 MODEX_TEXT +@TGP_NEXT_LINE . . . . . . . . . L Near 095E MODEX_TEXT +@TGP_NO_LEFT1BITS . . . . . . . L Near 092D MODEX_TEXT +@TGP_NO_MIDDLE1BITS . . . . . . L Near 0941 MODEX_TEXT +@TGP_NO_RIGHT1BITS . . . . . . . L Near 095D MODEX_TEXT +@TGP_Set_Char . . . . . . . . . L Near 08E1 MODEX_TEXT +@TPS_Exit . . . . . . . . . . . L Near 09EC MODEX_TEXT +@TPS_Print_It . . . . . . . . . L Near 09BC MODEX_TEXT +@code . . . . . . . . . . . . . Text MODEX_TEXT +@data . . . . . . . . . . . . . Text DGROUP +@fardata? . . . . . . . . . . . Text FAR_BSS +@fardata . . . . . . . . . . . . Text FAR_DATA +@stack . . . . . . . . . . . . . Text DGROUP +ACTIVE_PAGE . . . . . . . . . . Word 0012 _BSS +ALL_PLANES_ON . . . . . . . . . Number 0F02h +ALL_PLANES . . . . . . . . . . . Number 000Fh +ASYNC_RESET . . . . . . . . . . Number 0100h +ATTRIB_Ctrl . . . . . . . . . . Number 03C0h +CHAIN4_OFF . . . . . . . . . . . Number 0604h +CHARSET_HI . . . . . . . . . . . Word 0026 _BSS +CHARSET_LOW . . . . . . . . . . Word 0022 _BSS +CHAR_BITS . . . . . . . . . . . Number 000Fh +CRTC_Data . . . . . . . . . . . Number 03D5h +CRTC_Index . . . . . . . . . . . Number 03D4h +CURRENT_MOFFSET . . . . . . . . Word 001C _BSS +CURRENT_PAGE . . . . . . . . . . Word 0014 _BSS +CURRENT_SEGMENT . . . . . . . . Word 0016 _BSS +CURRENT_XOFFSET . . . . . . . . Word 0018 _BSS +CURRENT_YOFFSET . . . . . . . . Word 001A _BSS +Char_Plane_Data . . . . . . . . Byte 0008 MODEX_TEXT +DAC_READ_ADDR . . . . . . . . . Number 03C7h +DAC_WRITE_ADDR . . . . . . . . . Number 03C8h +DISPLAY_PAGE . . . . . . . . . . Word 0010 _BSS +False . . . . . . . . . . . . . Number 0000h +GC_Index . . . . . . . . . . . . Number 03CEh +GET_CHAR_PTR . . . . . . . . . . Number 1130h +INPUT_1 . . . . . . . . . . . . Number 03DAh +LAST_PAGE . . . . . . . . . . . Word 0004 _BSS +LATCHES_OFF . . . . . . . . . . Number FF08h +LATCHES_ON . . . . . . . . . . . Number 0008h +Left_Clip_Mask . . . . . . . . . Byte 0000 MODEX_TEXT +MAP_MASK_PLANE1 . . . . . . . . Number 0102h +MAP_MASK_PLANE2 . . . . . . . . Number 1102h +MAP_MASK . . . . . . . . . . . . Number 0002h +MAX_XOFFSET . . . . . . . . . . Word 001E _BSS +MAX_YOFFSET . . . . . . . . . . Word 0020 _BSS +MISC_OUTPUT . . . . . . . . . . Number 03C2h +MODE_200_Tall . . . . . . . . . L Near 0044 MODEX_TEXT +MODE_240_Tall . . . . . . . . . L Near 0054 MODEX_TEXT +MODE_320_Wide . . . . . . . . . L Near 0028 MODEX_TEXT +MODE_320x200 . . . . . . . . . . L Near 0074 MODEX_TEXT +MODE_320x240 . . . . . . . . . . L Near 00BC MODEX_TEXT +MODE_320x400 . . . . . . . . . . L Near 0086 MODEX_TEXT +MODE_320x480 . . . . . . . . . . L Near 00CE MODEX_TEXT +MODE_360_Wide . . . . . . . . . L Near 0036 MODEX_TEXT +MODE_360x200 . . . . . . . . . . L Near 00E0 MODEX_TEXT +MODE_360x240 . . . . . . . . . . L Near 0098 MODEX_TEXT +MODE_360x400 . . . . . . . . . . L Near 00F2 MODEX_TEXT +MODE_360x480 . . . . . . . . . . L Near 00AA MODEX_TEXT +MODE_400_Tall . . . . . . . . . L Near 0044 MODEX_TEXT +MODE_480_Tall . . . . . . . . . L Near 0054 MODEX_TEXT +MODE_Double_Line . . . . . . . . L Near 0020 MODEX_TEXT +MODE_Single_Line . . . . . . . . L Near 0018 MODEX_TEXT +MODE_TABLE . . . . . . . . . . . L Near 0064 MODEX_TEXT +NUM_MODES . . . . . . . . . . . Number 0008h +PAGE_ADDR . . . . . . . . . . . Word 0006 _BSS +PAGE_SIZE . . . . . . . . . . . Word 000E _BSS +PEL_DATA_REG . . . . . . . . . . Number 03C9h +PIXEL_PAN_REG . . . . . . . . . Number 0033h +PLANE_BITS . . . . . . . . . . . Number 0003h +READ_MAP . . . . . . . . . . . . Number 0004h +ROM_8x8_Hi . . . . . . . . . . . Number 0004h +ROM_8x8_Lo . . . . . . . . . . . Number 0003h +Right_Clip_Mask . . . . . . . . Byte 0004 MODEX_TEXT +SCREEN_HEIGHT . . . . . . . . . Word 0002 _BSS +SCREEN_WIDTH . . . . . . . . . . Word 0000 _BSS +SC_Data . . . . . . . . . . . . Number 03C5h +SC_Index . . . . . . . . . . . . Number 03C4h +SEQU_RESTART . . . . . . . . . . Number 0300h +START_DISP_HI . . . . . . . . . Number 000Ch +START_DISP_LO . . . . . . . . . Number 000Dh +True . . . . . . . . . . . . . . Number -0001h +VERT_RETRACE . . . . . . . . . . Number 0008h +VGA_Segment . . . . . . . . . . Number A000h +b . . . . . . . . . . . . . . . Text BYTE PTR +d . . . . . . . . . . . . . . . Text DWORD PTR +f . . . . . . . . . . . . . . . Text FAR PTR +nil . . . . . . . . . . . . . . Number 0000h +o . . . . . . . . . . . . . . . Text OFFSET +s . . . . . . . . . . . . . . . Text SHORT +w . . . . . . . . . . . . . . . Text WORD PTR + + 0 Warnings + 0 Errors diff --git a/src/lib/modex/modex.sbr b/src/lib/modex/modex.sbr new file mode 100755 index 00000000..4da653b0 Binary files /dev/null and b/src/lib/modex/modex.sbr differ diff --git a/src/lib/modex/modex105.zip b/src/lib/modex/modex105.zip new file mode 100755 index 00000000..9457bd98 Binary files /dev/null and b/src/lib/modex/modex105.zip differ diff --git a/src/lib/modex/packing.lst b/src/lib/modex/packing.lst new file mode 100755 index 00000000..88f817ca --- /dev/null +++ b/src/lib/modex/packing.lst @@ -0,0 +1,87 @@ + +PACKING LIST FOR MODEX104 + +DIRECTORY: \ - The Mode X Library versoon 1.04 + +ASM BAT 26 05-14-93 6:00p - Batch File to Assemble MODEX.ASM +MODE-X TXT 2135 05-14-93 6:00p - File Describing MODE X Routines +MODEX ASM 117039 05-14-93 6:00p - Assembly source to Mode X Library +MODEX BI 3238 05-14-93 6:00p - Include File for BASIC/PDS +MODEX H 2943 05-14-93 6:00p - Include File for C/C++ +MODEX OBJ 5208 05-14-93 6:00p - The Mode X Library +README DOC 3259 05-14-93 6:00p - Information on this Product +PACKING LST 4767 05-14-93 6:00p - This File + +DIRECTORY: \DEMOS - Mode X Demos + +CHARDEMO EXE 13066 05-14-93 6:00p - Demo of Multiple Fonts & Color Cycling +TEST6 EXE 19990 05-14-93 6:00p - Main Mode X Demo +ROM_8X8 FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE +SPACEAGE FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE +SYSTEM FNT 1024 05-14-93 6:00p - Font for CHARDEMO.EXE + +DIRECTORY: \DEMOS\BASIC7 - Demo Sources for Microsoft BASIC 7.1 (PDS) + +MAKE-LIB BAT 166 05-14-93 6:00p - Batch File to make MODEX.LIB/.QLB +MODEX BI 3238 05-14-93 6:00p - Include File for MODE X Library +MODEX LIB 7189 05-14-93 6:00p - Mode X & Utility Libraries for QBX +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library - Object File +MODEX QLB 11141 05-14-93 6:00p - Mode X & Utility Quick Library +TEST6 BAS 12733 05-14-93 6:00p - Main Demo Source Code (TEST6.EXE) +UASM-BC7 BAT 43 05-14-93 6:00p - Batch file to Make UTILS.OBJ for QBX +UTILS ASM 8506 05-14-93 6:00p - Basic Utilities - Assembler source +UTILS BI 2028 05-14-93 6:00p - Basic Utilities - Basic Includes +UTILS OBJ 681 05-14-93 6:00p - Basic Utilities - Object File +CHARDEMO BAS 3431 05-14-93 6:00p - Source to CHARDEMO.EXE + +DIRECTORY: \DEMOS\C - Demo Sources for Borland C/C++ + +C_UTILS ASM 8782 05-14-93 6:00p - C Utilities - Assembler source +C_UTILS H 2623 05-14-93 6:00p - C Utilities - C Includes +C_UTILS OBJ 648 05-14-93 6:00p - C Utilities - Object File +MODEX H 2943 05-14-93 6:00p - Mode X Library C Incldues +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library +UTLS-ASM BAT 36 05-14-93 6:00p - Batch File to Make C_UTILS.OBJ +X-DEMO C 15085 05-14-93 6:00p - Source to Main Demo (TEST6) in C +X-DEMO EXE 41090 05-14-93 6:00p - C Version of Main Demo +X-DEMO PRJ 5188 05-14-93 6:00p - Borland C Project file + +DIRECTORY: \DEMOS\PASCAL - Demo Sources for Turbo Pascal + +TEST5 PAS 15873 05-14-93 6:00p - Source for a TP Version of TEST6.EXE + +DIRECTORY: \DEMOS\QB45 - Demo Sources for Microsoft QuickBASIC 4.5 + +MAKE-LIB BAT 164 05-14-93 6:00p - Batch File to make MODEX.LIB/.QLB +MODEX BI 3238 05-14-93 6:00p - Include File for MODE X Library +MODEX LIB 7189 05-14-93 6:00p - Mode X & Utility Libraries for QB45 +MODEX OBJ 5208 05-14-93 6:00p - Mode X Library - Object File +MODEX QLB 9739 05-14-93 6:00p - Mode X & Utility Quick Library/QB45 +TEST6A BAS 12743 05-14-93 6:00p - Main Demo Source Code (TEST6.EXE) +TEST6A EXE 40544 05-14-93 6:00p - QB45 Version of Main Demo +UASM-QB4 BAT 30 05-14-93 6:00p - Batch file to Make UTILS.OBJ for QB45 +UTILS ASM 8506 05-14-93 6:00p - Basic Utilities - Assembler source +UTILS BI 2028 05-14-93 6:00p - Basic Utilities - Basic Includes +UTILS OBJ 628 05-14-93 6:00p - Basic Utilities - Object File + +DIRECTORY: \FONTEDIT - Font Editor + +CSEDIT EXE 39242 05-14-93 6:00p - Font Editor Program +CSEDIT DOC 8629 05-14-93 6:00p - Font Editor Documentation +CHARSETS CS 2144 05-14-93 6:00p - Internal Fonts for Editor +MOUSEIMG CS 128 05-14-93 6:00p - Mouse Pointers for Editor +PALETTE CS 768 05-14-93 6:00p - Palette for Editor +INVERSE FNT 1024 05-14-93 6:00p - Sample Font +ROM_8X8 FNT 1024 05-14-93 6:00p - Sample Font +SPACEAGE FNT 1024 05-14-93 6:00p - Sample Font +SYSTEM FNT 1024 05-14-93 6:00p - Sample Font + +DIRECTORY: \PALEDIT - Palette Editor + +PALEDIT EXE 31954 05-14-93 6:00p - Palette Editor Program +PALEDIT DOC 6688 05-14-93 6:00p - Palette Editor Documentation +CHARSETS CS 2144 05-14-93 6:00p - Internal Fonts for Editor +MOUSEIMG CS 128 05-14-93 6:00p - Mouse Pointers for Editor +GAMECOLR PAL 768 05-14-93 6:00p - Sample Palette +PRIME PAL 768 05-14-93 6:00p - Sample Palette +RGB PAL 768 05-14-93 6:00p - Sample Palette diff --git a/src/lib/modex/paledit/bakapi.pal b/src/lib/modex/paledit/bakapi.pal new file mode 100755 index 00000000..d4d4a6a0 Binary files /dev/null and b/src/lib/modex/paledit/bakapi.pal differ diff --git a/src/lib/modex/paledit/charsets.cs b/src/lib/modex/paledit/charsets.cs new file mode 100755 index 00000000..97fe608f Binary files /dev/null and b/src/lib/modex/paledit/charsets.cs differ diff --git a/src/lib/modex/paledit/diagonal.pal b/src/lib/modex/paledit/diagonal.pal new file mode 100755 index 00000000..5dee1969 Binary files /dev/null and b/src/lib/modex/paledit/diagonal.pal differ diff --git a/src/lib/modex/paledit/gamecolr.pal b/src/lib/modex/paledit/gamecolr.pal new file mode 100755 index 00000000..621b1e5e Binary files /dev/null and b/src/lib/modex/paledit/gamecolr.pal differ diff --git a/src/lib/modex/paledit/mouseimg.cs b/src/lib/modex/paledit/mouseimg.cs new file mode 100755 index 00000000..101e2084 Binary files /dev/null and b/src/lib/modex/paledit/mouseimg.cs differ diff --git a/src/lib/modex/paledit/paledit.doc b/src/lib/modex/paledit/paledit.doc new file mode 100755 index 00000000..61d0b2ee --- /dev/null +++ b/src/lib/modex/paledit/paledit.doc @@ -0,0 +1,166 @@ + +PALEDIT - A Simple VGA 256 Color Palette Editor + + +PALEDIT is distributed with MODEXnnn.ZIP, the general purpose MODE X +Library for VGA Graphics. + +WHAT YOU NEED TO RUN PALEDIT: + + * A Vga Monitor + * A Microsoft Compatible Mouse + + A Mouse is most definitely required, as the keyboard is used for + nothing except entering file names. + +FILES NEEDED IN THE CURRENT DIRECTORY: + + PALEDIT.EXE - The Palette Editor Program + CHARSETS.CS - The Palette Editor's Internal Fonts + MOUSEIMG.CS - The Palette Editor's Mouse Pointer + +SAMPLE PALETTE FILE THAT SHOULD BE INCLUDED: + + RGB.PAL - A Simple Palette with Reds, Greens, and Blues + PRIME.PAL - A Simple Palette + GAMECOLR.PAL - A Bright Palette from a Game of mine. + +WHAT IT EDITS: + + The VGA DAC Registers, all 256 of them. + +HOW IT WORKS/FEATURES: + + PALEDIT allows the user to see the entire VGA Palette of 256 colors + and select and modify the RED, GREEN, and BLUE values of any individual + color (DAC) register. The entire group of 256 colors can be saved to + a disk file for later retrieval. + + Individual "SLIDERS" show the current RED, GREEN, and BLUE color + components of the current color and allow them to be changed. + + The Following operations can be performed. + + * Raise, Lower, and set the RED, GREEN, or BLUE components. + * Copy the current RGB values to another Color (DAC) Register + * Brighten the selected color + * Darken and selected color + * Reset the selected color to its original state + * Blend an entire range of colors, creating a smooth + Transition from one color to another + * Optionally Lock out the first 16 colors to prevent + Accidental Modification + +DESCRIPTION OF OBJECTS/FEATURES FROM THE TOP DOWN: + + COLOR SLIDERS: In the upper left of the screen there are + Three Rectangular Boxes: One for each primary color: + RED, GREEN, and BLUE. Each Box has an arrow at each + end, and a scale bar in the middle, connecting the two + arrows. The scale bar is much like a thermometer, + indicating how much of that color is in the selected + color. To the right of each Box, the name of the color + is indicated, along with the content color in the form + of a number from 0 to 63; where 0 means none of that + color goes into making the selected color, and 63 means + that the selected color is saturated with that color. + + Clicking the mouse on the slider's left arrow box will + decrease the amount of that primary color in the selected + color. Holding the mouse button down will reduce the + color value all the way to 0. + + Clicking the mouse on the slider's right arrow box will + increase the amount of that primary color in the selected + color. Holding the mouse button down will increase the + color value all the way to 63. + + Clicking the mouse on the scale bar will set the amount + of that primary color to the value the represents that + position on the slider. + + LOCK Button: Clicking the button toggles the lockout of the + first 16 colors. When they are locked out, they can not + be modified, and when selected the word "LOCKED" will + appear below the color # on the Color Information Display. + + LOAD Button: Clicking this button will load the Palette file + that is named in the Palette File name box. If no name is + given or no such file exists, then nothing will be loaded. + + SAVE Button: Clicking this button will save the current Palette + in a file using the name given in the Palette File Name Box. + If a Valid name is not provided, nothing will be saved. + + QUIT Button: Clicking this button will return you to DOS. + Nothing is saved, and no confirmation is given. + + + Color Information Display: This Box is on the left side of the + Screen, below the Color Sliders. It shows the number of the + currently selected color (from 0 to 255) and indicates if + that color is locked. To the right of this box is a big + square showing the current color. + + LIGHTER Button: Clicking this button will make the selected + color brighter. + + DARKER Button: Clicking this button will make the selected + color darker. + + RESET Button: Clicking this button will restore the selected + color to the value it had when it was first selected. + + BLEND Button: Clicking this button will let you Blend a range + of colors together. One end of the range of colors is the + currently selected color. After Clicking the BLEND button. + You must click on the color at the other end of the range + in the Palette Display Box. All of the colors in between + those two colors will be changed to represent a gradual + transition from the color at one end to the color at the + other end. + + PALETTE FILE NAME BOX: This Text Box is used to enter the name + of a Palette file to load or the name to save the current + Palette as. Just click on the Box, and it will change color + and a flashing cursor will appear. Now you type in a filename + or edit the existing filename. Press or click + outside the text box to end editing. + + PALETTE DISPLAY BOX: This Box shows all 256 colors in an array + of 32 by 8 color blocks. The Currently Selected Color will + have a Box around it. Clicking on a color with the Left + Mouse button will make that color the new currently selected + color. Clicking on a color with the Right Mouse Button will + copy the color value from the old selected color to it, before + it is made the new selected color. + + Message Bar: At the very bottom of the screen, this Bar will display + information and messages for various functions. + +PALETTE FILE FORMAT: + + BINARY image, in order of VGA DAC (Color) Number. 3 Bytes Per + Color, 256 Colors. 768 Bytes total. The Files will be exactly + 768 bytes in size. + + COLOR: + RED: 1 BYTE + GREEN: 1 BYTE + BLUE: 1 BYTE + + PALETTE: Array (0 to 255) of COLOR + +COMMENTS, QUESTIONS, BUG REPORTS, etc: + + Send the to the Author: Matt Pritchard + + Through the 80xxx Fidonet Echo or + + Matt Pritchard + P.O. Box 140264 + Irving, TX 75014 + +CREDITS: + + This Palette Editor was written in QuickBASIC 4.5 diff --git a/src/lib/modex/paledit/paledit.exe b/src/lib/modex/paledit/paledit.exe new file mode 100755 index 00000000..f69e172d Binary files /dev/null and b/src/lib/modex/paledit/paledit.exe differ diff --git a/src/lib/modex/paledit/palview.exe b/src/lib/modex/paledit/palview.exe new file mode 100755 index 00000000..4c721d3b Binary files /dev/null and b/src/lib/modex/paledit/palview.exe differ diff --git a/src/lib/modex/paledit/prime.pal b/src/lib/modex/paledit/prime.pal new file mode 100755 index 00000000..310ca6e7 Binary files /dev/null and b/src/lib/modex/paledit/prime.pal differ diff --git a/src/lib/modex/paledit/rgb.pal b/src/lib/modex/paledit/rgb.pal new file mode 100755 index 00000000..bc03425d Binary files /dev/null and b/src/lib/modex/paledit/rgb.pal differ diff --git a/src/lib/modex/paledit/scroll.pal b/src/lib/modex/paledit/scroll.pal new file mode 100755 index 00000000..5dee1969 Binary files /dev/null and b/src/lib/modex/paledit/scroll.pal differ diff --git a/src/lib/modex/readme.doc b/src/lib/modex/readme.doc new file mode 100755 index 00000000..63a9053f --- /dev/null +++ b/src/lib/modex/readme.doc @@ -0,0 +1,76 @@ + +========================================================================= + þ þ þþþþþ þþþþ þþþþþ þ þ þ þþþþþ þ þ + þþ þþ þ þ þ þ þ þ þ þþ þ þ þ þ + þ þ þ þ þ þ þ þþþþ þ þ þ þ þ þþþþþ + þ þ þ þ þ þ þ þ þ þ þ þ þ + þ þ þþþþþ þþþþ þþþþþ þ þ þþþþþ þþ þþþþþ þ +========================================================================= + MODE X 1.04 +========================================================================= + Library & Editors by Matt Pritchard: Release 1.04 on 14 Mar 93 +========================================================================= + +MODEX104 is a library of high performance assembler routines for setting, +accessing, and manipulating the Undocumented 256 Color Modes available in +all VGA adaptors. + +MODEX104 includes the following elements: + + MODE X Library - A library of MODE X routines written in assembly. + + FONT EDITOR - An editor for creating and modifying fonts for use by + The MODE X Library. + + PALETTE EDITOR - An editor for creating and modifying palettes for + use in VGA 256 Color modes. + + MODE X Demos - Programs that show off the various features of the + MODE X Library + + MODE X Demo Source - The Full source code for the MODE X Demos for + the following Languages: Microsoft QuickBASIC 4.5, + Microsoft BASIC 7.1 PDS, Borland C/C++ 3.1, + and Borland Turbo Pascal. + +THE LEGAL STUFF: + + The Mode X Library has been placed into the Public Domain by the + Author (Matt Pritchard). The Font Editor and Palette Editor are also + placed into the Public Domain by the Author (Matt Pritchard). The + Source Code to the above editors is not in the Public Domain. + + The Mode X Demos and the Mode X Demo Sources have been placed into the + Public domain by the Author (Matt Pritchard). + + The Mode X Library may be used freely in any non commerical product. + It would be nice if the author was credited for the contribution, + but it is not necessary. No $$$ involved. + + The Mode X Library may be used freely in a commercial product, *IF* + the author (Matt Pritchard) is credited for the contribution. That's + it. No $$$ involved. + + The Mode X Library should not be re-sold or modified and re-sold. + No fee in excess of $5 should be charged for duplication of this + Library. + +CONTRIBUTORS: The following people have contributed to this effort. + + Michael Abrash - He told us all how to do it in the first place. + Scott Wyatt - He ported the Main Demo code to Turbo Pascal. + +THE AUTHOR: + + The author of MODEX104 is Matt Pritchard. + All Questions and correspondance can be directed to: + + "Matt Pritchard" on Fido Net ECHO Conference: 80xxx + + or mailed to: Matt Pritchard + P.O. Box 140264 + Irving, TX 75014-0264 + + Questions, Inquiries, Comments, Donations, etc are quite welcome. + + diff --git a/src/lib/modex/utls-asm.bat b/src/lib/modex/utls-asm.bat new file mode 100755 index 00000000..d996978f --- /dev/null +++ b/src/lib/modex/utls-asm.bat @@ -0,0 +1 @@ +MASM c_utils, c_utils, c_utils, nul; \ No newline at end of file diff --git a/src/lib/modex/w.sh b/src/lib/modex/w.sh new file mode 100755 index 00000000..4483916f --- /dev/null +++ b/src/lib/modex/w.sh @@ -0,0 +1,3 @@ +#! /bin/bash +wmake clean;wmake +cp x_demo.exe ../../../ diff --git a/src/lib/modex/x.exe b/src/lib/modex/x.exe new file mode 100755 index 00000000..7742d145 Binary files /dev/null and b/src/lib/modex/x.exe differ diff --git a/src/lib/modex/x_demo.c b/src/lib/modex/x_demo.c new file mode 100755 index 00000000..dfe9a3e0 --- /dev/null +++ b/src/lib/modex/x_demo.c @@ -0,0 +1,786 @@ +/* X-DEMO.C - a Mode "X" Demo */ +/* By Matt Pritchard, 14 Apr, 1993 */ + +#include +#include + +#include "modex.h" +#include "c_utils.h" + +#define MAX_SHAPES 32 +#define MAX_SPRITES 64 + + /* routines in this file */ + +void demo_res (int, int, int); +int get_key (void); +void error_out (char*); +void load_shapes (void); +int int_sqrt (int, int); +void page_demo (void); + + /* Structures for Sprites */ + +struct Shape +{ + unsigned char Image[512]; + int X_Width; + int Y_Width; +} Img [MAX_SHAPES]; + +struct Sprite +{ + int X_pos; + int Y_pos; + int X_Dir; + int Y_Dir; + int Shape; + int Last_X [2]; + int Last_Y [2]; +} Obj [MAX_SPRITES]; + + + /* MAIN */ + + +int main(int argc, char *argv[]) +{ + + /* if (argc > 0) + { + while (argc > 0) + { + dos_print ("Unknown Argument: "); + dos_print (makefp argv[argc]); + argc--; + } + return (0); + + } + */ + + init_random (); + + load_shapes (); + + demo_res ( Mode_320x200, 320, 200 ); + demo_res ( Mode_320x400, 320, 400 ); + + demo_res ( Mode_360x200, 360, 200 ); + demo_res ( Mode_360x400, 360, 400 ); + + demo_res ( Mode_320x240, 320, 240 ); + demo_res ( Mode_320x480, 320, 480 ); + + demo_res ( Mode_360x240, 360, 240 ); + demo_res ( Mode_360x480, 360, 480 ); + + page_demo (); + + set_video_mode (3); + dos_print ("This Mode X Demo is Finished"); + return (0); + +} + + + /* Demonstrate a given resolution */ + + +void demo_res (int Screen_Mode, int X_max, int Y_max) +{ + +char *Error1 = "Failure while calling SET_MODEX"; +char *Error2 = "Failure during READ_PIXEL test"; + +char *Abort_Msg = "Demo aborted by User"; + +char *Demo_Msg = " This is a MODE X demo "; +char *Scrn_Msg = "Screen Resolution is by "; +char *Cont_Msg = "Press to Continue"; + +char *Line_Msg = "LINE TEST"; +char *Fill_Msg = "FILL TEST"; +char *Pixel_Msg = "PIXEL TEST"; + +char Text[10]; + +int x1, y1, x2, y2 = 0; +int x, y, z = 0; +int X_Center, gap = 0; + + + if (set_modex (Screen_Mode) == 0) + { + error_out (Error1); + } + + X_Center = X_max / 2; + + x1 = 10; + y1 = 10; + x2 = X_max - 1; + y2 = Y_max - 1; + + for (z = 0; z <= 3; z++) + { + y = 31 - z -z; + draw_line (x1+z, y1+z, x2-z, y1+z, y); + draw_line (x1+z, y1+z, x1+z, y2-z, y); + draw_line (x1+z, y2-z, x2-z, y2-z, y); + draw_line (x2-z, y1+z, x2-z, y2-z, y); + } + + for (x = 0; x < (X_max / 10); x++) + { + tgprintc (48 + ((x+1) % 10), x*10+1, 1, 9 + ((x/8) % 7) ); + draw_line (x*10+9, 0, x*10+9, 3, c_bWHITE); + } + + for (y = 0; y < (Y_max / 10); y++) + { + tgprintc (48 + ((y+1) % 10), 1, y*10+1, 9 + ((y/10) % 7) ); + draw_line (0, y*10+9, 3, y*10+9, c_bWHITE); + } + + for (x = 0; x <= 63; x++) + { + z = 15 + (x * 3 / 4); + set_dac_register (64+x, z, z, z); + set_dac_register (128+x, 0, z, z); + + draw_line (103-x, 60, 40+x, 123, 64+x); + draw_line (40, 60+x, 103, 123-x, 128+x); + + } + + tprint_str (Line_Msg, 9, 37, 130, c_BLUE); + + y = 60; + gap = 0; + for (x = 0; x <= 9; x++) + { + fill_block (120, y, 120+x, y+gap, 64+x); + fill_block (140 - (15-x), y, 150+x, y+gap, 230+x); + fill_block (170 - (15-x), y, 170, y+gap, 128+x); + y = y + gap + 2; + gap++; + } + + tprint_str (Fill_Msg, 9, 110, 46, c_GREEN); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + set_point (x, y, z); + } + } + + tprint_str (Pixel_Msg, 10, 182, 130, c_RED); + + for (x = 190; x <= 250; x+=2) + { + for (y = 60; y <= 122; y+=2) + { + z = (x+x+y+y) & 0xff; + if (read_point(x, y) != z) + { + error_out (Error2); + } + } + } + + print_str (Demo_Msg, 23, X_Center - 92, 20, c_bRED, c_BLUE); + + x = X_Center - 124; + print_str (Scrn_Msg, 28, x, 30, c_bGREEN, c_BLACK); + + sprintf (Text, "%3d", X_max); + print_str (Text, 3, x+168, 30, c_bPURPLE, c_BLACK); + + sprintf (Text, "%3d", Y_max); + print_str (Text, 3, x + 224, 30, c_bWHITE, c_BLACK); + + for (x = 0; x <= 15; x++) + { + set_dac_register (230+x, 63-x*4, 0, 15+x*3); + draw_line (30+x, Y_max-6-x, X_max-20-x, Y_max-6-x, 230+x); + } + + tprint_str (Cont_Msg, 27, X_Center - 103, Y_max-18, c_YELLOW); + + if (get_key () == Ky_ESC) + { + error_out (Abort_Msg); + } + + return ; + +} + + + /* Wait for a Keystroke */ + + +int get_key(void) +{ + +int c = 0; + + while (c == 0) + { + c = scan_keyboard (); + } + + return (c); + +} + + + /* Error Handling Routine */ + + +void error_out (char * text) +{ + + set_video_mode (3); + dos_print (text); + exit (EXIT_SUCCESS); + +} + + + /* Routine to generate random sprites */ + + +void load_shapes () +{ + +unsigned char Grid[33][33]; + +char *Error1 = "Bad Shape Selected Error"; + +int Shape; +int x, y, z; +int Style, Color; +int X_Width, Y_Width, Center, S_Width; +int Hollow_X, Hollow_Y; + + for (Shape = 0; Shape < MAX_SHAPES; Shape++) + { + for (y = 0; y <= 32; y++) + { + for (x = 0; x <= 32; x++) + { + Grid[x][y] = c_BLACK; + } + } + + Style = random_int (6); + Color = 1 + random_int (15); + + switch (Style) + + { + /* SOLID BOXES */ + + case 0: + + { + do + { + X_Width = 3 + random_int(30); + Y_Width = 3 + random_int(30); + + } while ( (X_Width * Y_Width) >= 512); + + for (x = 1; x <= X_Width; x++) + { + for (y = 1; y <= Y_Width; y++) + { + Grid[x][y] = Color; + } + } + + break; + + } + /* HOLLOW BOXES */ + + case 1: + + { + do { + X_Width = 6 + random_int(27); + Y_Width = 6 + random_int(27); + } while ( (X_Width * Y_Width) >= 512); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Grid[x][y] = Color; + } + } + + Hollow_X = 1 + random_int ((X_Width / 2) -1); + Hollow_Y = 1 + random_int ((Y_Width / 2) -1); + + for (y = Hollow_Y+1; y <= Y_Width-Hollow_Y; y++) + { + for (x = Hollow_X+1; x <= X_Width-Hollow_X; x++) + { + Grid[x][y] = c_BLACK; + } + } + + break; + + } + + /* SOLID DIAMOND */ + + case 2: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + + break; + + } + + /* HOLLOW DIAMOND */ + + case 3: + + { + + X_Width = 3 + 2 * random_int(10); + Y_Width = X_Width; + Center = X_Width / 2; + S_Width = random_int (Center); + + for (y = 0; y <= Center; y++) + { + for (x = 0; x <= y; x++) + { + if ( x+(Center-y) >= S_Width ) + { + Grid [Center-x+1][y+1] = Color; + Grid [Center+x+1][y+1] = Color; + Grid [Center-x+1][Y_Width-y] = Color; + Grid [Center+x+1][Y_Width-y] = Color; + } + } + } + + break; + + } + + /* BALL */ + + case 4: + + { + + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if (z < Center) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + break; + } + + /* HOLLOW BALLS */ + + case 5: + + { + X_Width = 7 + 2 * random_int (8); + Y_Width = X_Width; + Center = 1 + X_Width / 2; + S_Width = random_int (X_Width); + + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + z = int_sqrt(Center-x, Center-y); + if ( (z < Center) && (z >= S_Width) ) + { + Grid[x][y] = 150 + Color * 2 + z * 3; + } + } + } + + + break; + } + + default: + + { + error_out (Error1); + break; + + } + + } + + z = 0; + for (y = 1; y <= Y_Width; y++) + { + for (x = 1; x <= X_Width; x++) + { + Img[Shape].Image[z] = Grid[x][y]; + z++; + } + } + + Img[Shape].X_Width = X_Width; + Img[Shape].Y_Width = Y_Width; + + } + + return; +} + + + /* Quickie Psuedo Integer Square Root Routine */ + + +int int_sqrt ( int x, int y ) +{ + +int Sqr_Table[12] = {1, 4, 9, 6, 25, 36, 49, 64, 81, 100, 121, 144}; + +int r, d; + + d = (x * x) + (y * y); + r = 0; + + while ( d >= Sqr_Table[r] ) + { + r++; + } + + return (r); + +} + + + /* The Bit Sprite Demo */ + + +void page_demo () +{ + +char *Error1 = "Failure during SET_VGA_MODEX (0, 320, 200, 2) call"; + +int Last_Objects[2], Visible_Objects; + +int Screen_X = 384; +int Screen_Y = 224; + +int x, y, z; +int c, dc; +int x1, y1, x2, y2; + +int Sprite_X, Sprite_Y; +int Current_Page; +int New_X, New_Y; + +int View_X, View_Y, View_Max, View_Cnt, View_XD, View_YD; +int Set_Color, Prev_Color, S_Dir, P_Dir; + +int Demo_Running = True; +int redo, code; + +int pee; +pee = set_vga_modex(Mode_320x200, Screen_X, Screen_Y, 3); + if ( pee > 0) + { + set_video_mode (3); + dos_print (Error1); + fprintf(stdout, "return value is %d\n", pee); + //error_out (Error1); + exit (EXIT_SUCCESS); + } + + set_active_page (0); + clear_vga_screen (c_BLACK); + + print_str ("This is a Test of the Following Functions:", 99, 10, 9, c_bWHITE, c_BLACK); + + draw_line (10, 18, 350, 18, c_YELLOW); + print_str ("SET_ACTIVE_PAGE", 99, 10, 20, c_bBLUE, c_BLACK); + print_str ("SET_DISPLAY_PAGE", 99, 10, 30, c_GREEN, c_BLACK); + print_str ("SET_DAC_REGISTER", 99, 10, 40, c_RED, c_BLACK); + print_str ("CLEAR_VGA_SCREEN", 99, 10, 50, c_CYAN, c_BLACK); + + print_str ("TDRAW_BITMAP", 99, 10, 60, c_PURPLE, c_BLACK); + print_str ("COPY_PAGE", 99, 10, 70, c_GREEN, c_BLACK); + print_str ("COPY_BITMAP", 99, 10, 80, c_CYAN, c_BLACK); + + print_str ("GPRINTC", 99, 10, 90, c_BLUE, c_BLACK); + print_str ("TGPRINTC", 99, 10, 100, c_GREEN, c_BLACK); + print_str ("SET_WINDOW", 99, 10, 110, c_RED, c_BLACK); + + print_str ("VIRTUAL SCREEN SIZES", 20, 190, 20, c_bBLUE, c_BLACK); + print_str (" SMOOTH SCROLLING", 20, 190, 30, c_GREEN, c_BLACK); + print_str (" SPRITE ANIMATION", 20, 190, 40, c_CYAN, c_BLACK); + print_str (" PAGE FLIPPING", 20, 190, 50, c_RED, c_BLACK); + print_str (" COLOR CYCLING", 20, 190, 60, c_PURPLE, c_BLACK); + + for (x = 0; x <=60; x++) + { + set_dac_register (50 + x, 3 + x, 0, 60 - x); + set_dac_register (150 + x, 3 + x, 0, 60 - x); + } + + c = 0; + dc = 1; + for (x = 0; x <= (Screen_X / 2); x++) + { + draw_line (Screen_X / 2 - 1, Screen_Y / 4, x, Screen_Y - 1, c + 50); + draw_line (Screen_X / 2, Screen_Y / 4, Screen_X - x - 1, Screen_Y - 1, c + 50); + c+= dc; + if ((c == 0) || (c == 60) ) { dc = -dc;} + } + + tprint_str ("Press to Continue", 99, 72, 190, c_bWHITE); + tprint_str ("< > = Faster < > = Slower", 99, 72, 204, c_bGREEN); + tprint_str ("< > = Fewer Shapes < > = More Shapes", 99, 32, 218, c_bCYAN); + + tgprintc (43, 80, 204, c_YELLOW); + tgprintc (45, 200, 204, c_YELLOW); + + tgprintc (25, 40, 218, c_YELLOW); + tgprintc (24, 200, 218, c_YELLOW); + + copy_page (0, 1); + copy_page (0, 2); + + for (x = 0; x < MAX_SPRITES; x++) + { + do { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + + Obj[x].Shape = x % MAX_SHAPES; + + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + Obj[x].X_pos = 1 + random_int(Screen_X - Sprite_X - 2); + Obj[x].Y_pos = 1 + random_int(Screen_Y - Sprite_Y - 2); + + Obj[x].Last_X[0] = Obj[x].X_pos; + Obj[x].Last_X[1] = Obj[x].X_pos; + Obj[x].Last_Y[0] = Obj[x].Y_pos; + Obj[x].Last_Y[1] = Obj[x].Y_pos; + + } + + Current_Page = 0; + + View_X = 0; + View_Y = 0; + View_Max = 3; + View_Cnt = 0; + View_XD = 1; + View_YD = 1; + + Set_Color = 3; + S_Dir = 1; + Prev_Color = 0; + P_Dir = 1; + + Visible_Objects = MAX_SPRITES / 2; + Last_Objects[0] = 0; + Last_Objects[1] = 0; + + while (Demo_Running) + { + + set_active_page (Current_Page); + + /* Erase Old Images */ + + for (x = 0; x <= Last_Objects[Current_Page]; x++) + { + z = 2; + y = Obj[x].Shape; + x1 = Obj[x].Last_X[Current_Page]; + y1 = Obj[x].Last_Y[Current_Page]; + x2 = x1 + Img[y].X_Width -1; + y2 = y1 + Img[y].Y_Width -1; + + x1 = x1 & 0xfffc; + x2 = x2 | 0x0003; + + copy_bitmap (z, x1, y1, x2, y2, Current_Page, x1, y1); + } + + /* Draw new images */ + + for (x = 0; x <= Visible_Objects; x++) + { + Sprite_X = Img[Obj[x].Shape].X_Width; + Sprite_Y = Img[Obj[x].Shape].Y_Width; + + /* Move Sprite */ + + do + { + redo = False; + New_X = Obj[x].X_pos + Obj[x].X_Dir; + + if (( New_X < 0 ) || (New_X + Sprite_X > Screen_X) ) + { + Obj[x].X_Dir = -Obj[x].X_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + Obj[x].X_pos = Obj[x].X_pos + Obj[x].X_Dir; + + + do + { + redo = False; + New_Y = Obj[x].Y_pos + Obj[x].Y_Dir; + + if ( (New_Y < 0) || (New_Y + Sprite_Y > Screen_Y) ) + { + Obj[x].Y_Dir = -Obj[x].Y_Dir; + if (random_int(20) == 1) + { + do + { + Obj[x].X_Dir = random_int(7) - 3; + Obj[x].Y_Dir = random_int(7) - 3; + } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) ); + redo = True; + } + } + } while (redo); + + Obj[x].Y_pos = Obj[x].Y_pos + Obj[x].Y_Dir; + + /* Draw Sprite */ + + tdraw_bitmap ((char far*) &Img[Obj[x].Shape], Obj[x].X_pos, Obj[x].Y_pos, Sprite_X, Sprite_Y); + + Obj[x].Last_X[Current_Page] = Obj[x].X_pos; + Obj[x].Last_Y[Current_Page] = Obj[x].Y_pos; + + } + + Last_Objects[Current_Page] = Visible_Objects; + + + /* Pan Screen Back & Forth */ + + View_Cnt++; + if (View_Cnt >= View_Max) + { + View_X+= View_XD; + if ( (View_X == 0) || (View_X == 39) ) {View_XD = -View_XD;} + if (View_XD < 0) + { + View_Y+= View_YD; + if ( (View_Y == 0) || (View_Y == 39) ) {View_YD = -View_YD;} + } + + set_window (Current_Page, View_X, View_Y); + + View_Cnt = 0; + } + else + { + set_display_page (Current_Page); + } + + /* Cycle Colors */ + + set_dac_register (50 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (50 + Set_Color, Set_Color, 10, 63 - Set_Color); + + set_dac_register (150 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color); + set_dac_register (150 + Set_Color, 63, 63, Set_Color); + + Set_Color+= S_Dir; + if ( (Set_Color == 60) || (Set_Color == 0) ) {S_Dir = -S_Dir;} + + Prev_Color+= P_Dir; + if ( (Prev_Color == 60) || (Prev_Color == 0) ) {P_Dir = -P_Dir;} + + /* Check for Keystroke */ + + Current_Page = Current_Page ^ 0x01; + + code = scan_keyboard (); + + if (code == Ky_ESC) {Demo_Running = False;} + + if (code == Ky_Plus) + { + if (View_Max < 12) {View_Max++;} + } + + if (code == Ky_Minus) + { + if (View_Max > 1) {View_Max--;} + if (View_Cnt >= View_Max) {View_Cnt = 0;} + } + + if (code == Ky_Up) + { + if (Visible_Objects < MAX_SPRITES-1) {Visible_Objects++;} + } + + if (code == Ky_Down) + { + if (Visible_Objects > 0) {Visible_Objects--;} + } + + } + +} diff --git a/src/lib/modex/x_demo.dsk b/src/lib/modex/x_demo.dsk new file mode 100755 index 00000000..5573e71a Binary files /dev/null and b/src/lib/modex/x_demo.dsk differ diff --git a/src/lib/modex/x_demo.exe b/src/lib/modex/x_demo.exe new file mode 100755 index 00000000..75369aba Binary files /dev/null and b/src/lib/modex/x_demo.exe differ diff --git a/src/lib/modex/x_demo.prj b/src/lib/modex/x_demo.prj new file mode 100755 index 00000000..b3f307e5 Binary files /dev/null and b/src/lib/modex/x_demo.prj differ diff --git a/test.exe b/test.exe index 218959c4..78e4ac32 100755 Binary files a/test.exe and b/test.exe differ diff --git a/test2.exe b/test2.exe index 243e4682..fb16b1f7 100755 Binary files a/test2.exe and b/test2.exe differ diff --git a/vgmtest.exe b/vgmtest.exe index 892afa7e..2ccb997a 100755 Binary files a/vgmtest.exe and b/vgmtest.exe differ diff --git a/x-demo.smp b/x-demo.smp new file mode 100755 index 00000000..42aafa32 Binary files /dev/null and b/x-demo.smp differ diff --git a/x_demo.exe b/x_demo.exe new file mode 100755 index 00000000..75369aba Binary files /dev/null and b/x_demo.exe differ diff --git a/x_demo.smp b/x_demo.smp new file mode 100755 index 00000000..85d0078f Binary files /dev/null and b/x_demo.smp differ