egacode.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. //Code to edit character sets and switch between ega 14 point mode and
  22. //vga 16 point mode
  23. //SMZX commented out -Koji
  24. #include "meminter.h"
  25. #include "charset.h"
  26. #include "string.h"
  27. #include <stdio.h>
  28. #include <dos.h>
  29. #include "egacode.h"
  30. //Current set- No reading of characters ever neccesary!
  31. unsigned char far *curr_set;//Size- 14*256 bytes
  32. static volatile int need_update=1;
  33. //Segment of character set memory
  34. #define CS_Seg 0xb800
  35. //Offset of character set 0 (the only one used)
  36. #define CS_Offs 0x0000
  37. //Pointer to character set memory, as unsigned char far
  38. #define CS_Ptr ((unsigned char far *)MK_FP(CS_Seg,CS_Offs))
  39. //Enter 14-byte high character mode and reset character sets
  40. //(EGA native text mode)
  41. void ega_14p_mode(void) {
  42. asm {
  43. mov ax,1201h
  44. mov bl,30h
  45. int 10h
  46. mov ax,0003h
  47. int 10h
  48. }
  49. }
  50. void smzx_14p_mode(void)
  51. {
  52. asm {
  53. mov ax,1201h
  54. mov bl,30h
  55. int 10h
  56. mov ax,0003h
  57. int 10h
  58. mov dx,03C0h
  59. mov al,10h
  60. out dx,al
  61. mov al,4Ch
  62. out dx,al
  63. }
  64. }
  65. //Enter 16-byte high character mode and reset character sets
  66. //(VGA native text mode)
  67. void vga_16p_mode(void) {
  68. asm {
  69. mov ax,1202h
  70. mov bl,30h
  71. int 10h
  72. mov ax,0003h
  73. int 10h
  74. }
  75. }
  76. //Access the character set part of the graphics memory (internal function)
  77. void _access_char_sets(void) {
  78. asm {
  79. mov al,5
  80. mov dx,3ceh
  81. out dx,al // outportb(0x3ce,5)
  82. mov al,0
  83. mov dx,3cfh
  84. out dx,al // outportb(0x3cf,0)
  85. mov al,6
  86. mov dx,3ceh
  87. out dx,al // outportb(0x3ce,6)
  88. mov al,0ch
  89. mov dx,3cfh
  90. out dx,al // outportb(0x3cf,0xc)
  91. mov al,4
  92. mov dx,3c4h
  93. out dx,al // outportb(0x3c4,4)
  94. mov al,6
  95. mov dx,3c5h
  96. out dx,al // outportb(0x3c5,6)
  97. mov al,2
  98. mov dx,3c4h
  99. out dx,al // outportb(0x3c4,2)
  100. mov al,4
  101. mov dx,3c5h
  102. out dx,al // outportb(0x3c5,4)
  103. mov dx,3ceh
  104. out dx,al // outportb(0x3ce,4)
  105. mov al,2
  106. mov dx,3cfh
  107. out dx,al // outportb(0x3cf,2)
  108. }
  109. }
  110. //Access the regular text memory (internal function)
  111. void _access_text(void) {
  112. asm {
  113. mov al,5
  114. mov dx,3ceh
  115. out dx,al // outportb(0x3ce,5)
  116. mov al,10h
  117. mov dx,3cfh
  118. out dx,al // outportb(0x3cf,0x10)
  119. mov al,6
  120. mov dx,3ceh
  121. out dx,al // outportb(0x3ce,6)
  122. mov al,0eh
  123. mov dx,3cfh
  124. out dx,al // outportb(0x3cf,0xe)
  125. mov al,4
  126. mov dx,3c4h
  127. out dx,al // outportb(0x3c4,4)
  128. mov al,2
  129. mov dx,3c5h
  130. out dx,al // outportb(0x3c5,2)
  131. mov dx,3c4h
  132. out dx,al // outportb(0x3c4,2)
  133. mov al,3
  134. mov dx,3c5h
  135. out dx,al // outportb(0x3c5,3)
  136. mov al,4
  137. mov dx,3ceh
  138. out dx,al // outportb(0x3ce,4)
  139. mov al,0
  140. mov dx,3cfh
  141. out dx,al // outportb(0x3cf,0)
  142. }
  143. }
  144. // Flags that the char set needs to be updated.
  145. void ec_need_update()
  146. {
  147. need_update = 1;
  148. }
  149. //Copies the set in memory (curr_set) to the real set in graphics memory
  150. void ec_update_set(void) {
  151. int remaining;
  152. unsigned char far *charac=CS_Ptr;
  153. unsigned char far *cset=curr_set;
  154. _access_char_sets();
  155. for ( remaining = 256 ; remaining
  156. ; remaining--, charac += 32, cset += 14 )
  157. {
  158. mem_cpy(charac, cset, 14);
  159. }
  160. _access_text();
  161. need_update = 0;
  162. }
  163. void ec_update_set_if_needed(void) {
  164. if (need_update) ec_update_set();
  165. }
  166. //Changes one byte of one character and updates it
  167. void ec_change_byte(int chr,int byte,int new_value) {
  168. unsigned char far *charac=CS_Ptr;
  169. curr_set[chr*14+byte]=new_value;
  170. _access_char_sets();
  171. charac[(chr<<5)+byte]=new_value;
  172. _access_text();
  173. }
  174. //Changes one entire 14-byte character and updates it
  175. void ec_change_char(int chr, unsigned char far *matrix) {
  176. unsigned char far *charac=CS_Ptr;
  177. mem_cpy(curr_set+chr*14, matrix, 14);
  178. _access_char_sets();
  179. mem_cpy(charac+(chr<<5), matrix, 14);
  180. _access_text();
  181. }
  182. //Changes one byte of one character WITHOUT updating it
  183. void ec_change_byte_nou(int chr,int byte,int new_value) {
  184. curr_set[chr*14+byte]=new_value;
  185. need_update = 1;
  186. }
  187. //Changes one entire 14-byte character WITHOUT updating it
  188. void ec_change_char_nou(int chr,unsigned char far *matrix) {
  189. mem_cpy(curr_set+chr*14, matrix, 14);
  190. need_update = 1;
  191. }
  192. //Reads one byte of a character
  193. int ec_read_byte(int chr,int byte) {
  194. return curr_set[chr*14+byte];
  195. }
  196. //Reads an entire 14-byte character
  197. void ec_read_char(int chr,unsigned char far *matrix) {
  198. mem_cpy(matrix, curr_set+chr*14, 14);
  199. }
  200. //Initialization function. Call AFTER setting mode with ega_14p.
  201. //Copies current set to curr_set and insures set 0 is activated.
  202. //Also copies current set to ascii_set. Also runs memory init, returns
  203. //non-0 for error.
  204. char ec_init(void) {
  205. curr_set=(unsigned char far *)farmalloc(3584);
  206. if(curr_set==NULL) return -1;
  207. //Copy default mzx to current and update
  208. mem_cpy((signed char far *)curr_set,
  209. (signed char far *)default_mzx_char_set, 3584);
  210. ec_update_set();
  211. //Done!
  212. return 0;
  213. }
  214. //Call upon exit to free memory
  215. void ec_exit(void) {
  216. if(curr_set!=NULL) farfree(curr_set);
  217. }
  218. // Saves a non 256 char character set to disk now,
  219. // also can take an offset from where it wants to start saving. - Exo
  220. char ec_save_set(char far *filename, int offset, int size)
  221. {
  222. FILE *fp;
  223. fp = fopen(filename, "wb");
  224. if(fp == NULL) return(-1);
  225. if((offset + size) > 256)
  226. {
  227. size = 256 - offset;
  228. }
  229. fwrite(curr_set + (offset * 14), 14, size, fp);
  230. fclose(fp);
  231. return(0);
  232. }
  233. //Load a character set from disk
  234. char ec_load_set_nou(char far *filename) {
  235. FILE *fp;
  236. fp=fopen(filename,"rb");
  237. if(fp==NULL) return -1;
  238. fread(curr_set,14,256,fp);
  239. fclose(fp);
  240. need_update = 1;
  241. return 0;
  242. }
  243. // Loads a charset into a variable position in the current one - Exo
  244. char ec_load_set_nou_var(char far *filename, int pos)
  245. {
  246. int size = 255;
  247. FILE *fp;
  248. fp=fopen(filename,"rb");
  249. if(fp==NULL) return -1;
  250. fseek(fp, 0, SEEK_END);
  251. size = ftell(fp) / 14;
  252. fseek(fp, 0, 0);
  253. if(size + pos > 256)
  254. {
  255. size = 255 - pos;
  256. }
  257. fread(curr_set + (pos * 14), 14, size, fp);
  258. fclose(fp);
  259. need_update = 1;
  260. return 0;
  261. }
  262. char ec_load_set(char far *filename) {
  263. char status;
  264. status = ec_load_set_nou(filename);
  265. if (!status) ec_update_set();
  266. return status;
  267. }
  268. //Loads a character set directly from memory (stil 3584 bytes)
  269. void ec_mem_load_set(unsigned char far *chars) {
  270. mem_cpy((signed char far *)curr_set,(signed char far *)chars,3584);
  271. ec_update_set();
  272. }
  273. //Loads in the default set (Megazeux)
  274. void ec_load_mzx(void) {
  275. ec_mem_load_set(default_mzx_char_set);
  276. }