gray.s 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. |******************************************************************************
  2. |
  3. | project name: GrayScale-Support for TIGCC
  4. | author: thomas.nussbaumer@gmx.net
  5. | Julien Muchembled (original implementation for UniversalOS)
  6. |
  7. |
  8. | compatible with HW1/HW2 on all AMS versions up to 2.05
  9. |
  10. |******************************************************************************
  11. |------------------------------------------------------------------------------
  12. | uncomment the following global to simulate HW2 on the VTI
  13. | (this will not use port 70001D, therefore it flickers extremely; additionally
  14. | the complete HW detection is bypassed and always reports HW2)
  15. |------------------------------------------------------------------------------
  16. |.globl ALWAYS_HW2_TESTING
  17. .xdef GrayOn,GrayOff,__D_plane,__L_plane,__gray_handle,__gray_hw_type
  18. .xdef __switch_cnt,__gray_old_int1_hw1,__gray_old_int1_hw2
  19. .xdef __gray_sync_n_count,__gray_plane_index
  20. .xdef __gray_dbl_offset,__L_plane2,__D_plane2
  21. .even
  22. |==============================================================================
  23. | EXPORTED: GrayOn function (turn grayscales on) - trashes d1/a0/a1
  24. |==============================================================================
  25. GrayOn:
  26. move.w (__gray_handle,%pc),%d0 | if __gray_handle is not 0 we have
  27. bne __gray_return_immediately | already allocated memory -> out here
  28. move.l %a5,-(%sp) | we have more than 2 ROM_CALLs
  29. move.l 0xc8.w,%a5 | so we should optimize
  30. lea (__switch_cnt,%pc),%a0 | reset plane switch counter to 0
  31. clr.l (%a0)
  32. bsr.s __gray_check_hw_version | evaluate HW version and store it
  33. lea (__gray_hw_type,%pc),%a0
  34. move.w %d0,(%a0)
  35. bsr __gray_init_mem | allocate and initialize memory
  36. move.l (%sp)+,%a5
  37. move.w (__gray_handle,%pc),%d0
  38. bne __gray_init_handler | jump to interrupt handler setup if
  39. | memory was allocated correctly
  40. |moveq #0x0,%d0 | otherwise return 0 (GrayOn failed)
  41. rts
  42. |==============================================================================
  43. | checks for HW version (VTI is treated as HW1, because port 0x70001D is not
  44. | emulated by the VTI and this would cause NEVER switch
  45. | planes behaviour if we would use the HW2 support)
  46. |
  47. | returns 0 in d0.w for HW1 and 1 for HW2
  48. |
  49. | IMPORTANT NOTE: This function patches 2 locations in the code of the
  50. | grayscale support depending on the HW version. Patching the
  51. | locations for both types IS necessary, because if a program
  52. | is transfered from one calc to another one the default values
  53. | got already overwritten (if program was not archived)
  54. |==============================================================================
  55. __gray_check_hw_version:
  56. .ifdef ALWAYS_HW2_TESTING
  57. bra.s __always_hw2_proceed
  58. .endif
  59. move.l %a5,%d0
  60. and.l #0xE00000,%d0 | get the ROM base
  61. move.l %d0,%a0
  62. moveq #0,%d0
  63. move.l 260(%a0),%a1 | get pointer to the hardware param block
  64. add.l #0x10000,%a0
  65. cmp.l %a0,%a1 | check if the HW parameter block is near
  66. bcc.s __gray_patches_for_hw1 | if it is too far, it is HW1
  67. cmp.w #22,(%a1) | check if the parameter block contains HW
  68. bls.s __gray_patches_for_hw1 | if it is too small, it is HW1
  69. cmp.l #1,22(%a1) | check the hardware version
  70. beq.s __gray_patches_for_hw1 | if not 1, it is HW2 (or an unknown HW)
  71. |--------------------------------------------------------------------------
  72. | check for VTI (trick suggested by Julien Muchembled)
  73. | optimized by Lionel Debroux
  74. |--------------------------------------------------------------------------
  75. trap #12 | enter supervisor mode. returns old (%sr) in %d0.w
  76. move.w #0x3000,%sr | set a non-existing flag in %sr (but keep s-flag !!)
  77. move.w %d0,%d1 | save %d0.w content in %d1
  78. move.w %sr,%d0 | get %sr content and check for non-existing flag
  79. move.w %d1,%sr | restore old %sr.
  80. lsl.w #3,%d0
  81. bpl.s __gray_hw2type_detected | flag not set -> no VTI
  82. |--------------------------------------------------------------------------
  83. | HW1 detected
  84. |--------------------------------------------------------------------------
  85. moveq #0,%d0
  86. |--------------------------------------------------------------------------
  87. | patches code for HW1 version
  88. |
  89. | necessary memory == 1 plane + 8 Bytes == 3848
  90. |
  91. | the additionally 8 bytes are necessary for rounding later to a multiple
  92. | of 8
  93. |--------------------------------------------------------------------------
  94. __gray_patches_for_hw1:
  95. lea (__gray_size_to_allocate,%pc),%a0
  96. move.w #0x0f08,(%a0)
  97. clr.w (__gray_size_to_add-__gray_size_to_allocate,%a0)
  98. rts
  99. |--------------------------------------------------------------------------
  100. | HW2 detected
  101. |--------------------------------------------------------------------------
  102. __gray_hw2type_detected:
  103. .ifdef ALWAYS_HW2_TESTING
  104. __always_hw2_proceed:
  105. .endif
  106. moveq #1,%d0
  107. |--------------------------------------------------------------------------
  108. | patches code for HW2 version
  109. |
  110. | necessary memory == 2 planes + 8 Bytes == 7688
  111. |
  112. | the additionally 8 bytes are necessary for rounding later to a multiple
  113. | of 8
  114. |--------------------------------------------------------------------------
  115. lea (__gray_size_to_allocate,%pc),%a0
  116. move.w #0x1e08,(%a0)
  117. move.w #0xf00,(__gray_size_to_add - __gray_size_to_allocate,%a0)
  118. rts
  119. __gray_hw_type: | stores HW type (0==HW1 or VTI 1==HW2)
  120. .word 0
  121. |==============================================================================
  122. | Interrupt 1 handler for HW1
  123. |==============================================================================
  124. __gray_int1_handler_hw1:
  125. movem.l %d0/%a0,-(%a7)
  126. |--------------------------------------------------------------------------
  127. | Load skip counter and increment it (count = (count+1)&0x3). Skip any
  128. | further operation if count is 1, 2 or 3. This means that every 4th call
  129. | of the INT1 handler is a candidate for a plane switch
  130. |--------------------------------------------------------------------------
  131. lea (__gray_skipcount,%pc),%a0
  132. addq.b #1,(%a0)
  133. andi.b #0x3,(%a0)+ | IMPORTANT: a0 points now to __gray_phase!
  134. bne.s __gray_proceed_old
  135. |--------------------------------------------------------------------------
  136. | to evaluate which plane we use counter __gray_phase. This counter
  137. | performs the following counting 8->4->0->8.
  138. | 0 will use D_plane pointer
  139. | 4 will use L_plane pointer
  140. | (8 will be skipped, so it stays at D_plane)
  141. |--------------------------------------------------------------------------
  142. move.w (%a0),%d0
  143. subq.w #4,%d0 | subtract 4 from phase counter
  144. bcc.s __gray_store | not negative -> don't reset
  145. moveq #0x8,%d0 | reset phase counter to 8
  146. __gray_store:
  147. move.w %d0,(%a0) | store new phase counter value
  148. cmp.b #8,%d0
  149. beq.s __gray_proceed_old | for value 8 we do nothing (dark plane
  150. | stays active)
  151. lea (__D_plane,%pc),%a0
  152. |--------------------------------------------------------------------------
  153. | doublebuffer extension ... add content of __gray_dbl_offset to %d0
  154. |--------------------------------------------------------------------------
  155. add.w (__gray_dbl_offset-__D_plane,%a0),%d0
  156. suba.w %d0,%a0
  157. move.l (%a0),%d0 | load the address of this plane
  158. lsr.l #3,%d0 | reduce to address / 8
  159. move.w %d0,0x600010 | set new plane startaddress
  160. lea (__switch_cnt,%pc),%a0 | increment switch count
  161. addq.l #1,(%a0)
  162. __gray_proceed_old:
  163. movem.l (%a7)+,%d0/%a0
  164. |--------------------------------------------------------------------------
  165. | JUMP to previous installed interrupt handler
  166. |--------------------------------------------------------------------------
  167. .word 0x4ef9 | "JMP address" opcode
  168. __gray_old_int1_hw1:
  169. .long 0x00000000 | address of old int1 gots stored here
  170. __gray_dummy1: | NOT used yet (just for alignment)
  171. .byte 0x00
  172. |------------------------------------------------------------------------------
  173. | __gray_skipcount is a one byte counter which performs the following counting:
  174. | 3 -> 0 -> 1 -> 2 -> 3
  175. |------------------------------------------------------------------------------
  176. __gray_skipcount:
  177. .byte 0x03
  178. __gray_phase:
  179. .word 0x04 | performs: 4->0->8->4
  180. __switch_cnt:
  181. .long 0x00000000
  182. |==============================================================================
  183. | INTERNAL: allocates memory
  184. |
  185. | modifies: __gray_handle
  186. | __gray_used_mem
  187. | __L_plane
  188. |
  189. | Note: __D_plane will not be changed by this function! (will be set by
  190. | __gray_init_handler)
  191. |==============================================================================
  192. __gray_init_mem:
  193. |--------------------------------------------------------------------------
  194. | HeapAllocHigh(HW1=3848 bytes or HW2=7688 bytes)
  195. |--------------------------------------------------------------------------
  196. movea.l (0x92*4,%a5),%a0 /* HeapAllocHigh */
  197. .word 0x4878 | opcode of "PEA #value"
  198. __gray_size_to_allocate: | the size gets patched !!
  199. .word 0x1e08
  200. jsr (%a0)
  201. addq.w #4,%a7
  202. lea (__gray_handle,%pc),%a0
  203. move.w %d0,(%a0)+ | store handle in handle variable
  204. beq.s __gray_init_return | alloc failed (handle=0) -> out here
  205. clr.w (%a0) | clears __gray_dbl_offset
  206. |--------------------------------------------------------------------------
  207. | HeapDeref(__gray_handle)
  208. |--------------------------------------------------------------------------
  209. move.w %d0,-(%a7)
  210. movea.l (0x96*4,%a5),%a0 /* HeapDeref */
  211. jsr (%a0)
  212. addq.l #2,%a7
  213. |--------------------------------------------------------------------------
  214. | align memory address to next 8-byte boundary and store address in
  215. | __gray_used_mem
  216. |
  217. | for HW1: __L_plane gets set to the same address as __gray_used_mem
  218. | for HW2: __L_plane gets set to __gray_used_mem + 0xf00
  219. |--------------------------------------------------------------------------
  220. move.l %a0,%d0
  221. addq.l #7,%d0
  222. andi.b #0xF8,%d0
  223. lea (__gray_used_mem,%pc),%a0
  224. move.l %d0,(%a0)
  225. .word 0x0680 | opcode of "ADDI.L #value,%a0"
  226. .word 0x0000
  227. __gray_size_to_add:
  228. .word 0x0F00 | gets patched (HW1:0 HW2:0x0f00)
  229. move.l %d0,(__L_plane - __gray_used_mem,%a0)
  230. __gray_init_return:
  231. rts
  232. |------------------------------------------------------------------------------
  233. | handle to allocated memory used by grayscale
  234. |------------------------------------------------------------------------------
  235. __gray_handle:
  236. .word 0
  237. |------------------------------------------------------------------------------
  238. | DOUBLEBUFFER extension
  239. |------------------------------------------------------------------------------
  240. __gray_dbl_offset: | has to be directly AFTER __gray_handle!!
  241. .word 0
  242. __L_plane2:
  243. .long 0x0
  244. __D_plane2:
  245. .long 0x0
  246. |------------------------------------------------------------------------------
  247. | pointer to light plane
  248. | HW1: same as __gray_used_mem
  249. | HW2: __gray_used_mem + 0xf00
  250. |------------------------------------------------------------------------------
  251. __L_plane:
  252. .long 0x00004c00
  253. |------------------------------------------------------------------------------
  254. | pointer to dark plane (set by __gray_init_handler)
  255. | HW1: 0x4c00
  256. | HW2: same as __gray_used_mem
  257. |------------------------------------------------------------------------------
  258. __D_plane:
  259. .long 0x00004c00
  260. |------------------------------------------------------------------------------
  261. | pointer to allocated memory ALIGNED to 8-byte boundary
  262. |------------------------------------------------------------------------------
  263. __gray_used_mem:
  264. .long 0x00004c00
  265. |------------------------------------------------------------------------------
  266. | This variable is very hard to describe. Indeed this isn't one variable,
  267. | but two variables combined in one.
  268. |
  269. | Description will be added later ....
  270. |------------------------------------------------------------------------------
  271. __gray_sync_n_count:
  272. .word 0x0000
  273. |------------------------------------------------------------------------------
  274. | holds the index of the plane which should be drawn next (NOTE: this label
  275. | is never addressed directly, but indirectly from label __gray_sync_n_count.
  276. | So don't move it do somewhere else!)
  277. |------------------------------------------------------------------------------
  278. __gray_plane_index:
  279. .word 0x0000
  280. |==============================================================================
  281. | Interrupt 1 handler for HW2
  282. |
  283. | port 70001D (bit 7) is used to synchronized to the LCD hardware. Here are the
  284. | docs of this port (taken from Johan Eilert's j89hw.txt)
  285. |
  286. | $70001D RW ($06)
  287. | :7 Toggles every FS (every time the LCD restarts at line 0)
  288. | :6-4 -
  289. | :3 Battery checker bit B (? ???)
  290. | :2 ? (set)
  291. | :1 Screen enable (clear this bit to shut down LCD)
  292. | :0 Battery checker bit A (? enable $600000:2)
  293. | (AMS:) The battery checker bits must both be set (AB=11) prior to
  294. | checking the voltage level with $600000:2. Then, after use, bit B
  295. | must be cleared (AB=10) while the battery trig hardware settles to
  296. | the "rest" voltage value (%111). Finally, both bits should be
  297. | cleared.
  298. |==============================================================================
  299. __gray_int1_handler_hw2:
  300. move.w %sr,-(%a7) | save content of status register on stack
  301. move.w #0x2700,%sr | disable ALL interrupts (no one should
  302. | interrupt us ...)
  303. movem.l %d0-%d7/%a0-%a6,-(%a7)
  304. __gray_startagain:
  305. moveq #0x0,%d1
  306. lea (__gray_sync_n_count,%pc),%a0
  307. move.w (%a0),%d0
  308. bne.s __gray_copy_first_or_sec | there is a third of the plane left to
  309. | copy -> do it now!
  310. move.l (%a0),%d0
  311. .ifdef ALWAYS_HW2_TESTING
  312. move.b %d0,%d1
  313. eor.b #0x80,%d1
  314. .else
  315. move.b 0x70001D,%d1 | get flipping bit
  316. eor.b %d0,%d1
  317. bpl __gray_to_oldint | not flipped yet -> proceed to previous
  318. | installed int handler
  319. .endif
  320. eor.l %d1,(%a0) | store new flip "bit" and reset the
  321. | work left status
  322. |--------------------------------------------------------------------------
  323. | NOTE: if we detect a pageflip we start our copying work with the lowest
  324. | third. this way it will not interfere with the LCD hardware refresh
  325. |
  326. | The 3 thirds are copied in the following order:
  327. |
  328. | last third -> first third -> second third
  329. |--------------------------------------------------------------------------
  330. move.w #0xA00,%d0
  331. __gray_copy_next_third:
  332. addq.w #1,(%a0)+
  333. bra.s __gray_perform_copying
  334. __gray_copy_first_or_sec:
  335. |--------------------------------------------------------------------------
  336. | if __gray_sync_n_count == 1 -> copy first third of screen
  337. | otherwise -> set __gray_sync_n_count to 0 and copy second third of screen
  338. |--------------------------------------------------------------------------
  339. subq.w #1,%d0
  340. beq.s __gray_copy_next_third
  341. clr.w (%a0)+
  342. move.w #0x500,%d0 | setup to copy second third of screen
  343. __gray_perform_copying:
  344. move.b (%a0),%d1 | fetch index of plane to draw next
  345. beq __gray_update_index | skip index 0 -> stay at darkplane
  346. |--------------------------------------------------------------------------
  347. | If we'll come here we will copy 1 third of the screen from a specific
  348. | plane to the video buffer at 0x4c00. Register D0 holds the offset of
  349. | which third should be copied and register D1 contains the "index" of the
  350. | "source" plane
  351. |
  352. | index = 0 -> darkplane (skipped, will not come here!)
  353. | index = 4 -> darkplane
  354. | index = 8 -> lightplane
  355. |
  356. | Due to the fact that the indices are cycled from 8 down to 0 the skipped
  357. | index 0 causes the darkplane to stay active twice as long as the light
  358. | plane.
  359. |
  360. | The copying is performed in a kind of "hardcore" style by using 13
  361. | registers. This way 52 Bytes are copied with a single instruction.
  362. |--------------------------------------------------------------------------
  363. |--------------------------------------------------------------------------
  364. | doublebuffer extension ... add content of __gray_dbl_offset to %d0
  365. |--------------------------------------------------------------------------
  366. add.w (__gray_dbl_offset,%pc),%d1
  367. neg.w %d1
  368. movea.l (__gray_used_mem,%pc,%d1.w),%a0
  369. lea 0x4C00.w,%a1
  370. adda.w %d0,%a0
  371. adda.w %d0,%a1
  372. movem.l (%a0)+,%d0-%d7/%a2-%a6
  373. movem.l %d0-%d7/%a2-%a6,(%a1)
  374. movem.l (%a0)+,%d0-%d7/%a2-%a6
  375. movem.l %d0-%d7/%a2-%a6,(0x34,%a1) | size of this instruction: 6 bytes
  376. movem.l (%a0)+,%d0-%d7/%a2-%a6 | size of this instruction: 4 bytes
  377. movem.l %d0-%d7/%a2-%a6,(0x68,%a1)
  378. movem.l (%a0)+,%d0-%d7/%a2-%a6
  379. movem.l %d0-%d7/%a2-%a6,(0x9C,%a1)
  380. movem.l (%a0)+,%d0-%d7/%a2-%a6
  381. movem.l %d0-%d7/%a2-%a6,(0xD0,%a1)
  382. movem.l (%a0)+,%d0-%d7/%a2-%a6
  383. movem.l %d0-%d7/%a2-%a6,(0x104,%a1)
  384. movem.l (%a0)+,%d0-%d7/%a2-%a6
  385. movem.l %d0-%d7/%a2-%a6,(0x138,%a1)
  386. movem.l (%a0)+,%d0-%d7/%a2-%a6
  387. movem.l %d0-%d7/%a2-%a6,(0x16C,%a1)
  388. movem.l (%a0)+,%d0-%d7/%a2-%a6
  389. movem.l %d0-%d7/%a2-%a6,(0x1A0,%a1)
  390. movem.l (%a0)+,%d0-%d7/%a2-%a6
  391. movem.l %d0-%d7/%a2-%a6,(0x1D4,%a1)
  392. movem.l (%a0)+,%d0-%d7/%a2-%a6
  393. movem.l %d0-%d7/%a2-%a6,(0x208,%a1)
  394. movem.l (%a0)+,%d0-%d7/%a2-%a6
  395. movem.l %d0-%d7/%a2-%a6,(0x23C,%a1)
  396. movem.l (%a0)+,%d0-%d7/%a2-%a6
  397. movem.l %d0-%d7/%a2-%a6,(0x270,%a1)
  398. movem.l (%a0)+,%d0-%d7/%a2-%a6
  399. movem.l %d0-%d7/%a2-%a6,(0x2A4,%a1)
  400. movem.l (%a0)+,%d0-%d7/%a2-%a6
  401. movem.l %d0-%d7/%a2-%a6,(0x2D8,%a1)
  402. movem.l (%a0)+,%d0-%d7/%a2-%a6
  403. movem.l %d0-%d7/%a2-%a6,(0x30C,%a1)
  404. movem.l (%a0)+,%d0-%d7/%a2-%a6
  405. movem.l %d0-%d7/%a2-%a6,(0x340,%a1)
  406. movem.l (%a0)+,%d0-%d7/%a2-%a6
  407. movem.l %d0-%d7/%a2-%a6,(0x374,%a1)
  408. movem.l (%a0)+,%d0-%d7/%a2-%a6
  409. movem.l %d0-%d7/%a2-%a6,(0x3A8,%a1)
  410. movem.l (%a0)+,%d0-%d7/%a2-%a6
  411. movem.l %d0-%d7/%a2-%a6,(0x3DC,%a1)
  412. movem.l (%a0)+,%d0-%d7/%a2-%a6
  413. movem.l %d0-%d7/%a2-%a6,(0x410,%a1)
  414. movem.l (%a0)+,%d0-%d7/%a2-%a6
  415. movem.l %d0-%d7/%a2-%a6,(0x444,%a1)
  416. movem.l (%a0)+,%d0-%d7/%a2-%a6
  417. movem.l %d0-%d7/%a2-%a6,(0x478,%a1)
  418. movem.l (%a0)+,%d0-%d7/%a2-%a6
  419. movem.l %d0-%d7/%a2-%a6,(0x4AC,%a1)
  420. movem.l (%a0)+,%d0-%d7
  421. movem.l %d0-%d7,(0x4E0,%a1)
  422. |--------------------------------------------------------------------------
  423. | evaluate if there is still a third of the screen to copy or if we
  424. | should proceed to the next plane
  425. |--------------------------------------------------------------------------
  426. __gray_update_index:
  427. lea (__gray_sync_n_count,%pc),%a0
  428. move.w (%a0)+,%d0
  429. beq __gray_startagain | no third left to copy -> check again
  430. | the pageflip bit if yet a pageflip
  431. | had occured
  432. subq.w #1,%d0
  433. bne.s __gray_to_oldint | if there is "copy work" left ->
  434. | don't modify the plane to display
  435. lea (__switch_cnt,%pc),%a1 | increment switch count here, because
  436. addq.l #1,(%a1) | a complete page was drawn if we come here
  437. subq.b #4,(%a0) | cycle __gray_plane_index by decrementing
  438. bcc.s __gray_to_oldint | it and wrap around to 8 if negative.
  439. move.b #0x8,(%a0)
  440. __gray_to_oldint:
  441. movem.l (%a7)+,%d0-%d7/%a0-%a6
  442. move.w (%a7)+,%sr | restore content of status register
  443. |--------------------------------------------------------------------------
  444. | JUMP to previous installed interrupt handler
  445. |--------------------------------------------------------------------------
  446. .word 0x4ef9 | opcode of "JMP address" instruction
  447. __gray_old_int1_hw2:
  448. .long 0x00000000
  449. |==============================================================================
  450. | INTERNAL: initialize grayscale handler
  451. |==============================================================================
  452. __gray_init_handler:
  453. lea (__L_plane,%pc),%a0
  454. move.w #0x3BF,%d1
  455. move.w (__gray_hw_type,%pc),%d0
  456. beq.s __gray_init_hw1_handler
  457. |--------------------------------------------------------------------------
  458. | HW2 specific initializations:
  459. |
  460. | (1) set __D_plane to __gray_used_mem
  461. | (2) copy content of 0x4c00 to darkplane
  462. | (3) "backup" old INT1 handler in __gray_old_int1_hw2 (the address part
  463. | of a JUMP address instruction at the end of the HW2 int handler)
  464. | (4) install our own INT1 HW2 handler
  465. |--------------------------------------------------------------------------
  466. movea.l (__gray_used_mem,%pc),%a1
  467. move.l %a1,(0x4,%a0) | set __D_plane
  468. lea 0x4C00.w,%a0
  469. move.w %d1,%d0
  470. __gray_cpy_d_plane:
  471. move.l (%a0)+,(%a1)+
  472. dbf %d0, __gray_cpy_d_plane
  473. lea (__gray_int1_handler_hw2,%pc),%a0
  474. | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  475. | the following command should be unnecessary; I commented it out (TOM)
  476. | (__L_plane should be already set by __gray_init_mem)
  477. | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  478. |move.l %a1,(__L_plane - __gray_int1_handler_hw2,%a0)
  479. move.l 0x64,(__gray_old_int1_hw2 - __gray_int1_handler_hw2,%a0)
  480. bra.s __gray_init_proceed
  481. |--------------------------------------------------------------------------
  482. | HW1 specific initializations:
  483. |
  484. | (1) "backup" old INT1 handler in __gray_old_int1_hw1 (the address part
  485. | of a JUMP address instruction at the end of the HW1 int handler)
  486. | (2) install our own INT1 HW1 handler
  487. |--------------------------------------------------------------------------
  488. __gray_init_hw1_handler:
  489. move.l (%a0),%a1
  490. lea (__gray_int1_handler_hw1,%pc),%a0
  491. move.l 0x64,(__gray_old_int1_hw1 - __gray_int1_handler_hw1,%a0)
  492. __gray_init_proceed:
  493. move.l %a0,%d2
  494. lea 0x600001,%a0
  495. moveq.l #2,%d0
  496. bclr.b %d0,(%a0)
  497. move.l %d2,0x64:w
  498. bset.b %d0,(%a0)
  499. __gray_clr_l_plane:
  500. |--------------------------------------------------------------------------
  501. | clear light plane (done for both HW types)
  502. |--------------------------------------------------------------------------
  503. clr.l (%a1)+
  504. dbf %d1, __gray_clr_l_plane
  505. |--------------------------------------------------------------------------
  506. | PortSet(__D_plane,239,127)
  507. |--------------------------------------------------------------------------
  508. move.l #0xEF007F,-(%a7)
  509. move.l (__D_plane,%pc),-(%a7)
  510. movea.l 0xC8,%a0
  511. movea.l (0x1A2*4,%a0),%a1 /* PortSet */
  512. jsr (%a1)
  513. addq.w #8,%a7
  514. __gray_ok:
  515. lea (__L_plane,%pc),%a0
  516. lea (__L_plane2,%pc),%a1
  517. move.l (%a0)+,(%a1)+ | copy __L_plane to __L_plane2
  518. move.l (%a0)+,(%a1)+ | copy __D_plane to __D_plane2
  519. __gray_return_immediately:
  520. moveq #0x1,%d0
  521. rts
  522. |==============================================================================
  523. | EXPORTED: GrayOff function (turn grayscales off)
  524. | NOTE: ALWAYS returns 1 !!
  525. |==============================================================================
  526. GrayOff:
  527. lea (__gray_handle,%pc),%a0
  528. tst.w (%a0)
  529. beq __gray_return_immediately | no handle? -> nothing to do
  530. move.w (%a0),-(%a7)
  531. clr.l (%a0) | 0->handle AND(!!) 0->__gray_dbl_offset
  532. lea 0x600001,%a0
  533. move.w (__gray_hw_type,%pc),%d0
  534. beq.s __gray_hw1_cleanup
  535. |--------------------------------------------------------------------------
  536. | cleanup for HW2 calcs
  537. |--------------------------------------------------------------------------
  538. moveq.l #2,%d0
  539. bclr.b %d0,(%a0)
  540. move.l (__gray_old_int1_hw2,%pc),0x64:w | restore old INT1 handler
  541. bset.b %d0,(%a0)
  542. movea.l (__D_plane,%pc),%a1
  543. lea 0x4C00.w,%a0
  544. move.w #0x3BF,%d0 | copy content of darkplane to 0x4c00
  545. __gray_dark2lcd:
  546. move.l (%a1)+,(%a0)+
  547. dbf %d0, __gray_dark2lcd
  548. bra.s __gray_continue_cleanup
  549. |--------------------------------------------------------------------------
  550. | cleanup for HW1 calcs (on HW1 0x4c00 is used as darkplane. We haven't to
  551. | set it)
  552. |--------------------------------------------------------------------------
  553. __gray_hw1_cleanup:
  554. move.w #0x980,(0x600010-0x600001,%a0) | restore used plane to 0x4c00
  555. move.l (__gray_old_int1_hw1,%pc),0x40064 | restore old INT1 handler
  556. | (We can use 0x40064 here because it is HW1 only.)
  557. __gray_continue_cleanup:
  558. lea (__L_plane,%pc),%a0 | restore plane pointers to 0x4c00 for sure
  559. lea 0x4C00.w,%a1
  560. move.l %a1,(%a0)+
  561. move.l %a1,(%a0)+
  562. move.l %a1,(%a0)
  563. |--------------------------------------------------------------------------
  564. | HeapFree(__gray_handle)
  565. |--------------------------------------------------------------------------
  566. movea.l 0xc8,%a0
  567. movea.l (0x97*4,%a0),%a0 /* HeapFree */
  568. jsr (%a0)
  569. addq.l #2,%a7
  570. |--------------------------------------------------------------------------
  571. | PortRestore()
  572. |--------------------------------------------------------------------------
  573. movea.l 0xc8,%a0
  574. movea.l (0x1A3*4,%a0),%a0 /* PortRestore */
  575. jsr (%a0)
  576. lea (__gray_sync_n_count,%pc),%a0
  577. clr.l (%a0)
  578. __gray_off_out:
  579. jbra __gray_ok
  580. | #############################################################################
  581. | Revision History
  582. | #############################################################################
  583. |
  584. | Revision 3.17 2006/10/30 07:24:15 Kevin Kofler
  585. | Bumped version to 3.55.
  586. | Size optimization by Martial Demolins (use moveq instead of bclr/bset #imm).
  587. |
  588. | Revision 3.16 2005/10/09 01:48:20 Kevin Kofler
  589. | Bumped version to 3.54.
  590. | Size optimization by Jesse Frey (register saving, ROM_CALL optimization),
  591. | spelling/typo fixes by Kevin Kofler.
  592. |
  593. | Revision 3.15 2005/08/22 20:23:40 Kevin Kofler
  594. | Bumped version to 3.53.
  595. | Fixed calls to GrayOn with grayscale already enabled.
  596. |
  597. | Revision 3.14 2005/07/02 02:56:36 Kevin Kofler
  598. | Bumped version to 3.52.
  599. |
  600. | Revision 3.13 2005/06/11 05:58:27 Kevin Kofler
  601. | Removed commented-out junk.
  602. | Remove Id and Log tags.
  603. |
  604. | Revision 3.12 2005/06/07 16:51:00 Lionel Debroux
  605. | Optimized the routine for size: saved 40 bytes.
  606. |
  607. | Revision 3.11 2004/02/25 03:49:03 Kevin Kofler
  608. | Don't use 0x40000 to set interrupts on code path that affect HW3.
  609. | Use 0xE00000 as ROM_base mask instead of 0x600000.
  610. | Bumped version to 3.51.
  611. |
  612. | Revision 3.10 2002/04/05 11:34:23 tnussb
  613. | (1) Resets now __D_plane2,__L_plane2 and __gray_dbl_offset at end of GrayOn()
  614. | to make sure nothing happens if doublebuffer macros get called without
  615. | setting a buffer first. Nevertheless NO program should call one of the
  616. | doublebuffer macros without setting a buffer previously.
  617. | (2) Some further size optimizations. Now the size is exactly as long as
  618. | without before the integration of doublebuffering. Quite smart, isn't it?
  619. | More functionality, some minor drawbacks fixed and no increase in size ...
  620. | (3) Changed return value of GrayOff() function to void.
  621. |
  622. | Revision 3.9 2002/04/04 18:50:36 tnussb
  623. | first working version of internal doublebuffer support (not checked on
  624. | real calcs yet, but on the VTI)
  625. |
  626. | Revision 3.8 2002/04/04 16:39:05 tnussb
  627. | Debug version checked in previously. This one is the correct one.
  628. |
  629. | Revision 3.7 2002/04/04 16:35:20 tnussb
  630. | (1) documentation of HW2 interrupt handler heavily extended
  631. | (2) HW2: plane switch counting fixed (was incremented too often previously)
  632. | (3) global ALWAYS_HW2_TESTING added which can be used to force the use of
  633. | HW2 grayscales. Now the HW2 grayscales can be tested on the VTI if
  634. | this global is defined. Of course this will flicker extremely, because
  635. | the VTI doesn't simulate port 70001D, but its still better than no
  636. | testing possibility.
  637. | (4) don't trashes %sr on HW2 anymore (restores previous setting)
  638. | (5) This version was tested on a real HW1 and a real HW2 calc. It works.
  639. | (Thanx to Sebastian Reichelt and stoopid guy)
  640. |
  641. | Revision 3.6 2002/04/04 11:58:19 tnussb
  642. | (1) size optimizations
  643. | (2) unnecessary cleanup removed from GrayOff()
  644. | (3) interrupt handler for HW1 rewritten (uses now plane pointer directly)
  645. | (4) "heavily" documented
  646. |
  647. | Revision 3.5 2002/04/04 11:54:39 tnussb
  648. | (1) exports __gray_old_int1_hw1 and __gray_old_int1_hw2. this way it is
  649. | possible to modify them after grayscales are turned on
  650. | (2) comments changed to GNU Assembler style
  651. | [NOTE: CVS time and date doesn't fit to real implementation data]
  652. |
  653. | Revision 3.0 2002/04/04 11:50:56 tnussb
  654. | grayscale support used for TIGCC up to version v0.93
  655. | [NOTE: CVS time and date doesn't fit to real implementation data]
  656. |