123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660 |
- |******************************************************************************
- |
- | project name: GrayScale-Support for TIGCC
- | author: thomas.nussbaumer@gmx.net
- | Julien Muchembled (original implementation for UniversalOS)
- |
- |
- | compatible with HW1/HW2 on all AMS versions up to 2.05
- |
- |
- | $Id$
- |******************************************************************************
- |------------------------------------------------------------------------------
- | uncomment the following global to simulate HW2 on the VTI
- | (this will not use port 70001D, therefore it flickers extremely; additionally
- | the complete HW detection is bypassed and always reports HW2)
- |------------------------------------------------------------------------------
- |.globl ALWAYS_HW2_TESTING
- .xdef GrayOn,GrayOff,__D_plane,__L_plane,__gray_handle,__gray_hw_type
- .xdef __switch_cnt,__gray_old_int1_hw1,__gray_old_int1_hw2
- .xdef __gray_sync_n_count,__gray_plane_index
- .xdef __gray_dbl_offset,__L_plane2,__D_plane2
- .even
- |==============================================================================
- | EXPORTED: GrayOn function (turn grayscales on) - trashes d1/a0/a1
- |==============================================================================
- GrayOn:
- movem.l %d2-%d7/%a2-%a6,-(%a7)
- lea (__switch_cnt,%pc),%a0 | reset plane switch counter to 0
- move.l #0,(%a0)
- bsr.s __gray_check_hw_version | evaluate HW version and store it
- lea (__gray_hw_type,%pc),%a0
- move.w %d0,(%a0)
- bsr __gray_init_mem | allocate and initialize memory
- movem.l (%a7)+,%d2-%d7/%a2-%a6
- move.w (__gray_handle,%pc),%d0
- bne __gray_init_handler | jump to interrupt handler setup if
- | memory was allocated correctly
- moveq #0x0,%d0 | otherwise return 0 (GrayOn failed)
- rts
- |==============================================================================
- | checks for HW version (VTI is treated as HW1, because port 0x70001D is not
- | emulated by the VTI and this would cause NEVER switch
- | planes behaviour if we would use the HW2 support)
- |
- | returns 0 in d0.w for HW1 and 1 for HW2
- |
- | IMPORTANT NOTE: This function patches 2 locations in the code of the
- | grayscale support depending on the HW version. Patching the
- | locations for both types IS necessary, because if a program
- | is transfered from one calc to another one the default values
- | got already overwritten (if program was not archived)
- |==============================================================================
- __gray_check_hw_version:
- .ifdef ALWAYS_HW2_TESTING
- bra.s __always_hw2_proceed
- .endif
- move.l 0xc8,%d0
- and.l #0xE00000,%d0 | get the ROM base
- move.l %d0,%a0
- moveq #0,%d0
- move.l 260(%a0),%a1 | get pointer to the hardware param block
- add.l #0x10000,%a0
- cmp.l %a0,%a1 | check if the HW parameter block is near
- bcc.s __gray_patches_for_hw1 | if it is too far, it is HW1
- cmp.w #22,(%a1) | check if the parameter block contains HW
- bls.s __gray_patches_for_hw1 | if it is too small, it is HW1
- cmp.l #1,22(%a1) | check the hardware version
- beq.s __gray_patches_for_hw1 | if not 1, it is HW2 (or an unknown HW)
- |--------------------------------------------------------------------------
- | check for VTI (trick suggested by Julien Muchembled)
- |--------------------------------------------------------------------------
- trap #12 | enter supervisor mode. returns old (%sr) in %d0.w
- move.w #0x3000,%sr | set a non-existing flag in %sr (but keep s-flag)
- swap %d0 | save %d0.w content in upper part of %d0
- move.w %sr,%d0 | get %sr content and check for non-existing flag
- btst #12,%d0 | this non-existing flag can only be set on the VTI
- beq.s __gray_hw2type_detected | flag not set -> no VTI
- |--------------------------------------------------------------------------
- | HW1 detected
- |--------------------------------------------------------------------------
- swap %d0 | restore old %sr content and return 0
- move.w %d0,%sr
- moveq #0,%d0
- |--------------------------------------------------------------------------
- | patches code for HW1 version
- |
- | necessary memory == 1 plane + 8 Bytes == 3848
- |
- | the additionally 8 bytes are necessary for rounding later to a multiple
- | of 8
- |--------------------------------------------------------------------------
- __gray_patches_for_hw1:
- lea (__gray_size_to_allocate,%pc),%a0
- move.w #0x0f08,(%a0)
- move.w #0,(__gray_size_to_add-__gray_size_to_allocate,%a0)
- rts
- |--------------------------------------------------------------------------
- | HW2 detected
- |--------------------------------------------------------------------------
- __gray_hw2type_detected:
- swap %d0 | restore old %sr content and set return to 1
- move.w %d0,%sr
- .ifdef ALWAYS_HW2_TESTING
- __always_hw2_proceed:
- .endif
- moveq #1,%d0
- |--------------------------------------------------------------------------
- | patches code for HW2 version
- |
- | necessary memory == 2 planes + 8 Bytes == 7688
- |
- | the additionally 8 bytes are necessary for rounding later to a multiple
- | of 8
- |--------------------------------------------------------------------------
- lea (__gray_size_to_allocate,%pc),%a0
- move.w #0x1e08,(%a0)
- move.w #0xf00,(__gray_size_to_add - __gray_size_to_allocate,%a0)
- rts
- __gray_hw_type: | stores HW type (0==HW1 or VTI 1==HW2)
- .word 0
- |==============================================================================
- | Interrupt 1 handler for HW1
- |==============================================================================
- __gray_int1_handler_hw1:
- movem.l %d0/%a0,-(%a7)
- |--------------------------------------------------------------------------
- | Load skip counter and increment it (count = (count+1)&0x3). Skip any
- | further operation if count is 1, 2 or 3. This means that every 4th call
- | of the INT1 handler is a candidate for a plane switch
- |--------------------------------------------------------------------------
- lea (__gray_skipcount,%pc),%a0
- addq.b #1,(%a0)
- andi.b #0x3,(%a0)+ | IMPORTANT: a0 points now to __gray_phase!
- bne.s __gray_proceed_old
- |--------------------------------------------------------------------------
- | to evaluate which plane we use counter __gray_phase. This counter
- | performs the following counting 8->4->0->8.
- | 0 will use D_plane pointer
- | 4 will use L_plane pointer
- | (8 will be skipped, so it stays at D_plane)
- |--------------------------------------------------------------------------
- move.w (%a0),%d0
- subq.w #4,%d0 | subtract 4 from phase counter
- bcc.s __gray_store | not negative -> don't reset
- moveq #0x8,%d0 | reset phase counter to 8
- __gray_store:
- move.w %d0,(%a0) | store new phase counter value
- cmp.b #8,%d0
- beq.s __gray_proceed_old | for value 8 we do nothing (dark plane
- | stays active)
- lea (__D_plane,%pc),%a0
- |--------------------------------------------------------------------------
- | doublebuffer extension ... add content of __gray_dbl_offset to %d0
- |--------------------------------------------------------------------------
- add.w (__gray_dbl_offset-__D_plane,%a0),%d0
- suba.w %d0,%a0
- move.l (%a0),%d0 | load the address of this plane
- lsr.l #3,%d0 | reduce to address / 8
- move.w %d0,0x600010 | set new plane startaddress
- lea (__switch_cnt,%pc),%a0 | increment switch count
- addq.l #1,(%a0)
- __gray_proceed_old:
- movem.l (%a7)+,%d0/%a0
- |--------------------------------------------------------------------------
- | JUMP to previous installed interrupt handler
- |--------------------------------------------------------------------------
- .word 0x4ef9 | "JMP address" opcode
- __gray_old_int1_hw1:
- .long 0x00000000 | address of old int1 gots stored here
- __gray_dummy1: | NOT used yet (just for alignment)
- .byte 0x00
- |------------------------------------------------------------------------------
- | __gray_skipcount is a one byte counter which performs the following counting:
- | 3 -> 0 -> 1 -> 2 -> 3
- |------------------------------------------------------------------------------
- __gray_skipcount:
- .byte 0x03
- __gray_phase:
- .word 0x04 | performs: 4->0->8->4
- __switch_cnt:
- .long 0x00000000
- |==============================================================================
- | INTERNAL: allocates memory
- |
- | modifies: __gray_handle
- | __gray_used_mem
- | __L_plane
- |
- | Note: __D_plane will not be changed by this function! (will be set by
- | __gray_init_handler)
- |==============================================================================
- __gray_init_mem:
- lea (__gray_handle,%pc),%a5 | if __gray_handle is not 0
- tst.w (%a5) | we have already allocated
- bne.s __gray_init_return | memory -> out here
- |--------------------------------------------------------------------------
- | HeapAllocHigh(HW1=3848 bytes or HW2=7688 bytes)
- |--------------------------------------------------------------------------
- movea.l 0xc8,%a0
- lea (0x92*4,%a0),%a0 /* HeapAllocHigh */
- .word 0x4878 | opcode of "PEA #value"
- __gray_size_to_allocate: | the size gets patched !!
- .word 0x1e08
- movea.l (%a0),%a2
- jsr (%a2)
- addq.w #4,%a7
- move.w %d0,(%a5)+ | store handle in handle variable
- beq.s __gray_init_return | alloc failed (handle=0) -> out here
- clr.w (%a5) | clears __gray_dbl_offset
- |--------------------------------------------------------------------------
- | HeapDeref(__gray_handle)
- |--------------------------------------------------------------------------
- move.w %d0,-(%a7)
- movea.l 0xc8,%a0
- lea (0x96*4,%a0),%a0 /* HeapDeref */
- movea.l (%a0),%a2
- jsr (%a2)
- addq.l #2,%a7
- |--------------------------------------------------------------------------
- | align memory address to next 8-byte boundary and store address in
- | __gray_used_mem
- |
- | for HW1: __L_plane gets set to the same address as __gray_used_mem
- | for HW2: __L_plane gets set to __gray_used_mem + 0xf00
- |--------------------------------------------------------------------------
- move.l %a0,%d0
- addq.l #7,%d0
- andi.b #0xF8,%d0
- lea (__gray_used_mem,%pc),%a0
- move.l %d0,(%a0)
- .word 0x0680 | opcode of "ADDI.L #value,%a0"
- .word 0x0000
- __gray_size_to_add:
- .word 0x0F00 | gets patched (HW1:0 HW2:0x0f00)
- move.l %d0,(__L_plane - __gray_used_mem,%a0)
- __gray_init_return:
- rts
- |------------------------------------------------------------------------------
- | handle to allocated memory used by grayscale
- |------------------------------------------------------------------------------
- __gray_handle:
- .word 0
- |------------------------------------------------------------------------------
- | DOUBLEBUFFER extension
- |------------------------------------------------------------------------------
- __gray_dbl_offset: | has to be directly AFTER __gray_handle!!
- .word 0
- __L_plane2:
- .long 0x0
- __D_plane2:
- .long 0x0
- |------------------------------------------------------------------------------
- | pointer to light plane
- | HW1: same as __gray_used_mem
- | HW2: __gray_used_mem + 0xf00
- |------------------------------------------------------------------------------
- __L_plane:
- .long 0x00004c00
- |------------------------------------------------------------------------------
- | pointer to dark plane (set by __gray_init_handler)
- | HW1: 0x4c00
- | HW2: same as __gray_used_mem
- |------------------------------------------------------------------------------
- __D_plane:
- .long 0x00004c00
- |------------------------------------------------------------------------------
- | pointer to allocated memory ALIGNED to 8-byte boundary
- |------------------------------------------------------------------------------
- __gray_used_mem:
- .long 0x00004c00
- |------------------------------------------------------------------------------
- | This variable is very hard to describe. Indeed this isn't one variable,
- | but two variables combined in one.
- |
- | Description will be added later ....
- |------------------------------------------------------------------------------
- __gray_sync_n_count:
- .word 0x0000
- |------------------------------------------------------------------------------
- | holds the index of the plane which should be drawn next (NOTE: this label
- | is never addressed directly, but indirectly from label __gray_sync_n_count.
- | So don't move it do somewhere else!)
- |------------------------------------------------------------------------------
- __gray_plane_index:
- .word 0x0000
- |==============================================================================
- | Interrupt 1 handler for HW2
- |
- | port 70001D (bit 7) is used to synchronized to the LCD hardware. Here are the
- | docs of this port (taken from Johan Eilert's j89hw.txt)
- |
- | $70001D RW ($06)
- | :7 Toggles every FS (every time the LCD restarts at line 0)
- | :6-4 -
- | :3 Battery checker bit B (? ???)
- | :2 ? (set)
- | :1 Screen enable (clear this bit to shut down LCD)
- | :0 Battery checker bit A (? enable $600000:2)
- | (AMS:) The battery checker bits must both be set (AB=11) prior to
- | checking the voltage level with $600000:2. Then, after use, bit B
- | must be cleared (AB=10) while the battery trig hardware settles to
- | the "rest" voltage value (%111). Finally, both bits should be
- | cleared.
- |==============================================================================
- __gray_int1_handler_hw2:
- move.w %sr,-(%a7) | save content of status register on stack
- move.w #0x2700,%sr | disable ALL interrupts (no one should
- | interrupt us ...)
- movem.l %d0-%d7/%a0-%a6,-(%a7)
- __gray_startagain:
- moveq #0x0,%d1
- lea (__gray_sync_n_count,%pc),%a0
- move.w (%a0),%d0
- bne.s __gray_copy_first_or_sec | there is a third of the plane left to
- | copy -> do it now!
- move.l (%a0),%d0
- .ifdef ALWAYS_HW2_TESTING
- move.b %d0,%d1
- eor.b #0x80,%d1
- .else
- move.b 0x70001D,%d1 | get flipping bit
- eor.b %d0,%d1
- bpl __gray_to_oldint | not flipped yet -> proceed to previous
- | installed int handler
- .endif
- eor.l %d1,(%a0) | store new flip "bit" and reset the
- | work left status
- |--------------------------------------------------------------------------
- | NOTE: if we detect a pageflip we start our copying work with the lowest
- | third. this way it will not interfere with the LCD hardware refresh
- |
- | The 3 thirds are copied in the following order:
- |
- | last third -> first third -> second third
- |--------------------------------------------------------------------------
- move.w #0xA00,%d0
- __gray_copy_next_third:
- addq.w #1,(%a0)+
- bra.s __gray_perform_copying
- __gray_copy_first_or_sec:
- |--------------------------------------------------------------------------
- | if __gray_sync_n_count == 1 -> copy first third of screen
- | otherwise -> set __gray_sync_n_count to 0 and copy second third of screen
- |--------------------------------------------------------------------------
- subq.w #1,%d0
- beq.s __gray_copy_next_third
- clr.w (%a0)+
- move.w #0x500,%d0 | setup to copy second third of screen
- __gray_perform_copying:
- move.b (%a0),%d1 | fetch index of plane to draw next
- beq __gray_update_index | skip index 0 -> stay at darkplane
- |--------------------------------------------------------------------------
- | If we'll come here we will copy 1 third of the screen from a specific
- | plane to the video buffer at 0x4c00. Register D0 holds the offset of
- | which third should be copied and register D1 contains the "index" of the
- | "source" plane
- |
- | index = 0 -> darkplane (skipped, will not come here!)
- | index = 4 -> darkplane
- | index = 8 -> lightplane
- |
- | Due to the fact that the indices are cycled from 8 down to 0 the skipped
- | index 0 causes the darkplane to stay active twice as long as the light
- | plane.
- |
- | The copying is performed in a kind of "hardcore" style by using 13
- | registers. This way 52 Bytes are copied with a single instruction.
- |--------------------------------------------------------------------------
- |--------------------------------------------------------------------------
- | doublebuffer extension ... add content of __gray_dbl_offset to %d0
- |--------------------------------------------------------------------------
- add.w (__gray_dbl_offset,%pc),%d1
- neg.w %d1
- movea.l (__gray_used_mem,%pc,%d1.w),%a0
- lea 0x4C00,%a1
- adda.w %d0,%a0
- adda.w %d0,%a1
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x34,%a1) | size of this instruction: 6 bytes
- movem.l (%a0)+,%d0-%d7/%a2-%a6 | size of this instruction: 4 bytes
- movem.l %d0-%d7/%a2-%a6,(0x68,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x9C,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0xD0,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x104,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x138,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x16C,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x1A0,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x1D4,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x208,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x23C,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x270,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x2A4,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x2D8,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x30C,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x340,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x374,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x3A8,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x3DC,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x410,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x444,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x478,%a1)
- movem.l (%a0)+,%d0-%d7/%a2-%a6
- movem.l %d0-%d7/%a2-%a6,(0x4AC,%a1)
- movem.l (%a0)+,%d0-%d7
- movem.l %d0-%d7,(0x4E0,%a1)
- |--------------------------------------------------------------------------
- | evaluate if there is still a third of the screen to copy or if we
- | should proceed to the next plane
- |--------------------------------------------------------------------------
- __gray_update_index:
- lea (__gray_sync_n_count,%pc),%a0
- move.w (%a0)+,%d0
- beq __gray_startagain | no third left to copy -> check again
- | the pageflip bit if yet a pageflip
- | had occured
- subq.w #1,%d0
- bne.s __gray_to_oldint | if there is "copy work" left ->
- | don't modify the plane to display
- lea (__switch_cnt,%pc),%a1 | increment switch count here, because
- addq.l #1,(%a1) | a complete page was drawn if we come here
- subq.b #4,(%a0) | cycle __gray_plane_index by decrementing
- bcc.s __gray_to_oldint | it and wrap around to 8 if negative.
- move.b #0x8,(%a0)
- __gray_to_oldint:
- movem.l (%a7)+,%d0-%d7/%a0-%a6
- move.w (%a7)+,%sr | restore content of status register
- |--------------------------------------------------------------------------
- | JUMP to previous installed interrupt handler
- |--------------------------------------------------------------------------
- .word 0x4ef9 | opcode of "JMP address" instruction
- __gray_old_int1_hw2:
- .long 0x00000000
- |==============================================================================
- | INTERNAL: initialize grayscale handler
- |==============================================================================
- __gray_init_handler:
- lea (__L_plane,%pc),%a0
- move.w #0x3BF,%d1
- move.w (__gray_hw_type,%pc),%d0
- tst.w %d0
- beq.s __gray_init_hw1_handler
- |--------------------------------------------------------------------------
- | HW2 specific initializations:
- |
- | (1) set __D_plane to __gray_used_mem
- | (2) copy content of 0x4c00 to darkplane
- | (3) "backup" old INT1 handler in __gray_old_int1_hw2 (the address part
- | of a JUMP address instruction at the end of the HW2 int handler)
- | (4) install our own INT1 HW2 handler
- |--------------------------------------------------------------------------
- movea.l (__gray_used_mem,%pc),%a1
- move.l %a1,(0x4,%a0) | set __D_plane
- movea.w #0x4C00,%a0
- move.w %d1,%d0
- __gray_cpy_d_plane:
- move.l (%a0)+,(%a1)+
- dbf %d0, __gray_cpy_d_plane
- lea (__gray_int1_handler_hw2,%pc),%a0
- | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- | the following command should be unnecessary; I commented it out (TOM)
- | (__L_plane should be already set by __gray_init_mem)
- | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- |move.l %a1,(__L_plane - __gray_int1_handler_hw2,%a0)
- move.l 0x64,(__gray_old_int1_hw2 - __gray_int1_handler_hw2,%a0)
- bra.s __gray_init_proceed
- |--------------------------------------------------------------------------
- | HW1 specific initializations:
- |
- | (1) "backup" old INT1 handler in __gray_old_int1_hw1 (the address part
- | of a JUMP address instruction at the end of the HW1 int handler)
- | (2) install our own INT1 HW1 handler
- |--------------------------------------------------------------------------
- __gray_init_hw1_handler:
- move.l (%a0),%a1
- lea (__gray_int1_handler_hw1,%pc),%a0
- move.l 0x64,(__gray_old_int1_hw1 - __gray_int1_handler_hw1,%a0)
- __gray_init_proceed:
- bclr.b #2,0x600001
- move.l %a0,0x64:w
- bset.b #2,0x600001
- __gray_clr_l_plane:
- |--------------------------------------------------------------------------
- | clear light plane (done for both HW types)
- |--------------------------------------------------------------------------
- clr.l (%a1)+
- dbf %d1, __gray_clr_l_plane
- |--------------------------------------------------------------------------
- | PortSet(__D_plane,239,127)
- |--------------------------------------------------------------------------
- move.l #0xEF007F,-(%a7)
- move.l (__D_plane,%pc),-(%a7)
- movea.l 0xC8,%a0
- lea (0x1A2*4,%a0),%a0 /* PortSet */
- movea.l (%a0),%a1
- jsr (%a1)
- addq.w #8,%a7
- __gray_ok:
- lea (__L_plane,%pc),%a0
- lea (__L_plane2,%pc),%a1
- move.l (%a0)+,(%a1)+ | copy __L_plane to __L_plane2
- move.l (%a0)+,(%a1)+ | copy __D_plane to __D_plane2
- moveq #0x1,%d0
- rts
- |==============================================================================
- | EXPORTED: GrayOff function (turn grayscales off)
- | NOTE: ALWAYS returns 1 !!
- |==============================================================================
- GrayOff:
- movem.l %a2-%a3,-(%a7)
- lea (__gray_handle,%pc),%a3
- tst.w (%a3)
- beq __gray_off_out | no handle? -> nothing to do
- move.w (__gray_hw_type,%pc),%d0
- tst.w %d0
- beq.s __gray_hw1_cleanup
- |--------------------------------------------------------------------------
- | cleanup for HW2 calcs
- |--------------------------------------------------------------------------
- bclr.b #2,0x600001
- move.l (__gray_old_int1_hw2,%pc),0x64:w | restore old INT1 handler
- bset.b #2,0x600001
- movea.l (__D_plane,%pc),%a1
- movea.w #0x4C00,%a0
- move.w #0x3BF,%d0 | copy content of darkplane to 0x4c00
- __gray_dark2lcd:
- move.l (%a1)+,(%a0)+
- dbf %d0, __gray_dark2lcd
- bra.s __gray_continue_cleanup
- |--------------------------------------------------------------------------
- | cleanup for HW1 calcs (on HW1 0x4c00 is used as darkplane. We haven't to
- | set it)
- |--------------------------------------------------------------------------
- __gray_hw1_cleanup:
- move.w #0x980,0x600010 | restore used plane to 0x4c00
- move.l (__gray_old_int1_hw1,%pc),0x40064 | restore old INT1 handler
- | (We can use 0x40064 here because it is HW1 only.)
- __gray_continue_cleanup:
- lea (__L_plane,%pc),%a0 | restore plane pointers to 0x4c00 for sure
- move.l #0x04c00,(%a0)+
- move.l #0x04c00,(%a0)+
- move.l #0x04c00,(%a0)
- |--------------------------------------------------------------------------
- | HeapFree(__gray_handle)
- |--------------------------------------------------------------------------
- movea.l 0xc8,%a0
- lea (0x97*4,%a0),%a0 /* HeapFree */
- move.w (%a3),-(%a7)
- move.l (%a0),%a2
- jsr (%a2)
- addq.l #2,%a7
- |--------------------------------------------------------------------------
- | PortRestore()
- |--------------------------------------------------------------------------
- movea.l 0xc8,%a0
- lea (0x1A3*4,%a0),%a0 /* PortRestore */
- move.l (%a0),%a2
- jsr (%a2)
- clr.l (%a3) | 0->handle AND(!!) 0->__gray_dbl_offset
- lea (__gray_sync_n_count,%pc),%a0
- clr.l (%a0)
- __gray_off_out:
- movem.l (%a7)+,%a2-%a3
- jbra __gray_ok
- | #############################################################################
- | Revision History
- | #############################################################################
- |
- | $Log: not supported by cvs2svn $
- | Revision 3.11 2004/02/25 03:49:03 Kevin Kofler
- | Don't use 0x40000 to set interrupts on code path that affect HW3.
- | Use 0xE00000 as ROM_base mask instead of 0x600000.
- | Bumped version to 3.51.
- |
- | Revision 3.10 2002/04/05 11:34:23 tnussb
- | (1) Resets now __D_plane2,__L_plane2 and __gray_dbl_offset at end of GrayOn()
- | to make sure nothing happens if doublebuffer macros get called without
- | setting a buffer first. Nevertheless NO program should call one of the
- | doublebuffer macros without setting a buffer previously.
- | (2) Some further size optimizations. Now the size is exactly as long as
- | without before the integration of doublebuffering. Quite smart, isn't it?
- | More functionality, some minor drawbacks fixed and no increase in size ...
- | (3) Changed return value of GrayOff() function to void.
- |
- | Revision 3.9 2002/04/04 18:50:36 tnussb
- | first working version of internal doublebuffer support (not checked on
- | real calcs yet, but on the VTI)
- |
- | Revision 3.8 2002/04/04 16:39:05 tnussb
- | Debug version checked in previously. This one is the correct one.
- |
- | Revision 3.7 2002/04/04 16:35:20 tnussb
- | (1) documentation of HW2 interrupt handler heavily extended
- | (2) HW2: plane switch counting fixed (was incremented too often previously)
- | (3) global ALWAYS_HW2_TESTING added which can be used to force the use of
- | HW2 grayscales. Now the HW2 grayscales can be tested on the VTI if
- | this global is defined. Of course this will flicker extremely, because
- | the VTI doesn't simulate port 70001D, but its still better than no
- | testing possibility.
- | (4) don't trashes %sr on HW2 anymore (restores previous setting)
- | (5) This version was tested on a real HW1 and a real HW2 calc. It works.
- | (Thanx to Sebastian Reichelt and stoopid guy)
- |
- | Revision 3.6 2002/04/04 11:58:19 tnussb
- | (1) size optimizations
- | (2) unnecessary cleanup removed from GrayOff()
- | (3) interrupt handler for HW1 rewritten (uses now plane pointer directly)
- | (4) "heavily" documented
- |
- | Revision 3.5 2002/04/04 11:54:39 tnussb
- | (1) exports __gray_old_int1_hw1 and __gray_old_int1_hw2. this way it is
- | possible to modify them after grayscales are turned on
- | (2) comments changed to GNU Assembler style
- | [NOTE: CVS time and date doesn't fit to real implementation data]
- |
- | Revision 3.0 2002/04/04 11:50:56 tnussb
- | grayscale support used for TIGCC up to version v0.93
- | [NOTE: CVS time and date doesn't fit to real implementation data]
- |
|