gray.s 28 KB

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