home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- *
- * f7.ca: more routines for ST text screen dump:
- * part 2 of 3.
- * Megamax in-line version.
- *
- *
- ******************************************************************/
-
-
- /****
- *
- * save_screen-- saves a block of memory (screen memory) so
- * that we can then fool around with it with impunity
- * (relatively speaking).
- *
- * The block is either the entire screen or a "window"
- * defined by variables set by 'set_window'.
- *
- * It is assumed that the two blocks do not overlap.
- *
- * at entry:
- * (a6) + 8 -> start of source block.
- * (a6) + 12 -> size of block (in words).
- * (a6) + 16 -> start of destination block.
- * (a6) + 20 -> resolution index.
- *
- * at exit:
- * all registers preserved.
- *
- *
- ****/
- #ifdef SC_IMAGE
- save_screen:
- link A6,#0 ;frame pointer
- movem.l A0-A2/A4/D0-D7,-(A7) ;save registers
-
- move.l #-1,D0 ;get a4
- bsr reg_a4 ;do it
- clr.l D6 ;clear transfer register
- clr.l D5 ;clear for word
- move.w xshift(A4),D5 ;get shift factor
- movea.l 8(A6),A0 ;get source block start
- move.l 12(A6),D0 ;size == count
- movea.l 16(A6),A1 ;get dest block start
- move.l 20(A6),D1 ;resolution index
- bne.s s_sn_001 ;if not low res
- bsr save_low
- bra s_sn_003
- s_sn_001: subq.l #1,D1 ;ix now == 0 or 1
- dbf D1,s_sn_002 ;if == 1, high res
- bsr save_med ;else med res
- bra s_sn_003
- s_sn_002: bsr save_high ;high res save
-
- s_sn_003:
- movem.l (A7)+,A0-A2/A4/D0-D7 ;restore registers
- unlk A6 ;deallocate frame
- rts ;return
- #endif
-
- /****
- *
- * save_low-- save screen memory, 4 bit planes.
- * save_med-- save screen memory, 2 bit planes.
- * save_high-- save screen memory, 1 bit plane.
- *
- * History tells us that the first bit planes were used in background
- * shots during the filming of the "Battle of Britain". Since then many
- * more uses have been found for bit planes, particularly in computer
- * architecture. Bit planes have been found to be particularly useful
- * in confusing computer programmers. Advanced computers are now often
- * found with several different bit-plane configurations, thus enabling
- * them to confuse several programmers at the same time. Unfortunately,
- * only one programmer worked on this project.
- *
- * at entry:
- * a0 == source block start.
- * d0 == size of block in words.
- * a1 == dest block start.
- * d2 == length of line in bytes.
- * d5 == shift factor for byte alignment.
- * d7 == odd/even offset flag. (0xff => odd)
- *
- * at exit:
- * a0,a1,d0,d2-d6 destroyed.
- * all other registers preserved.
- *
- *
- ****/
- save_high:
- suba.l back(A4),A0
- bra high_test
- high_loop:
- adda.l back(A4),A0 ;get to end of screen line
- adda.l front(A4),A0 ;get to start of window line
- move.l resolution(A4),D2 ;length of line in bytes
- bra.s line_h_test
- line_h:
- /* this is the shift code for non-byte-aligned windows */
- move.b (A0)+,D6 ;get "this" byte
- lsl.w #BYTESIZE,D6 ;shift it in register
- move.b (A0),D6 ;get next byte
- lsl.w D5,D6 ;align both
- lsr.w #BYTESIZE,D6 ;now access low byte
- move.b D6,(A1)+ ;and save it
-
- line_h_test:
- dbf D2,line_h ;do one line
- high_test:
- dbf D0,high_loop ;continue to end
- rts
-
- /****
- ****/
- save_med:
- clr.l D7 ;clear flag register
- move.l front(A4),D3 ;front offset
- move.l back(A4),D4 ;back offset
- roxr.l #1,D3 ;get low bit of 'front'
- scs D7 ;set flag
- andi.l #-2,D4 ;make back offset even
- lsl.l #2,D3 ;re-align offset & double it
- lsl.l #1,D4 ;'back' * 2 too
- suba.l D4,A0 ;anticipate first loop
- bra med_test ;start save
- med_loop:
- adda.l D4,A0 ;get to end of screen line
- adda.l D3,A0 ;get to start of window line
- move.l resolution(A4),D2 ;line length
- tst.b D7 ;odd offset?
- beq line_m_test ;if not
- bra line_modd ;else start in mid of word
- line_m:
- move.b 0(A0),D1 ;first plane
- or.b 2(A0),D1 ;then second plane
- lsl.w #BYTESIZE,D1 ;move byte over
- move.b 1(A0),D1 ;get next byte
- or.b 3(A0),D1 ;and second plane
- lsl.w D5,D1 ;align data
- lsr.w #BYTESIZE,D1 ;recover first byte
- move.b D1,(A1)+ ;store data
- line_modd:
- dbf D2,line_mnxt ;finished this line?
- addq.l #4,A0 ;if so, index to next
- bra med_test ;and go
- line_mnxt:
- move.b 1(A0),D1 ;else: 1st plane next group
- or.b 3(A0),D1 ;get second
- lsl.w #BYTESIZE,D1 ;move byte over
- move.b 4(A0),D1 ;get next byte
- or.b 6(A0),D1 ;and second plane
- lsl.w D5,D1 ;align data
- lsr.w #BYTESIZE,D1 ;recover first byte
- move.b D1,(A1)+ ;save it
- addq.l #4,A0 ;index to next line
- line_m_test:
- dbf D2,line_m ;finish line
- med_test:
- dbf D0,med_loop ;continue to end
- rts
-
-
- /****
- ****/
- save_low:
- clr.l D7 ;clear flag register
- move.l front(A4),D3 ;front offset
- move.l back(A4),D4 ;back offset
- roxr.l #1,D3 ;get low bit of 'front'
- scs D7 ;set flag
- andi.l #-2,D4 ;make back offset even
- lsl.l #3,D3 ; * 4 for 4 planes
- lsl.l #2,D4
- suba.l D4,A0 ;anticipate first loop
- bra low_test ;start save
- low_loop:
- adda.l D4,A0 ;get to end of screen line
- adda.l D3,A0 ;get to start of window line
- move.l resolution(A4),D2 ;get line length
- tst.b D7 ;odd offset?
- beq line_l_test ;if not
- bra line_lodd ;else start at odd byte
-
- line_l:
- move.b 0(A0),D1 ;first plane
- or.b 2(A0),D1 ;second plane
- or.b 4(A0),D1 ;third plane
- or.b 6(A0),D1 ;fourth plane
- lsl.w #BYTESIZE,D1
- move.b 1(A0),D1
- or.b 3(A0),D1
- or.b 5(A0),D1
- or.b 7(A0),D1
- lsl.w D5,D1
- lsr.w #BYTESIZE,D1
- move.b D1,(A1)+ ;store it
- line_lodd:
- dbf D2,line_lnxt ;finished this line?
- addq.l #8,A0 ;next word-group
- bra low_test ;if so
- line_lnxt:
- move.b 1(A0),D1 ;now get next byte of data
- or.b 3(A0),D1 ;and second plane
- or.b 5(A0),D1 ;and third plane
- or.b 7(A0),D1 ;and fourth plane
- lsl.w #BYTESIZE,D1
- move.b 8(A0),D1
- or.b 10(A0),D1
- or.b 12(A0),D1
- or.b 14(A0),D1
- lsl.w D5,D1
- lsr.w #BYTESIZE,D1
- move.b D1,(A1)+
- addq.l #8,A0
- line_l_test:
- dbf D2,line_l ;finish line
- low_test:
- dbf D0,low_loop ;continue to end
- rts ;dummy comment
-
-
- /*****
- *
- * justify-- takes byte address in saved screen memory and returns
- * the byte address of the beginning of the row in which
- * the original address lay.
- * In NO_IMAGE version, also transfers a text line's worth
- * of screen data into storage area, shifting the data if
- * necessary to byte-align it.
- * Uses code in 'save_screen' (above).
- *
- * at entry:
- * (a6) + 8 -> byte address.
- *
- * at exit:
- * (a6) + 8 -> justified address (i.e., result is
- * on stack).
- *
- * if NO_IMAGE is defined, then the next text line of screen data
- * is stored into 'one_line'.
- *
- *
- *****/
- justify:
- link A6,#0 ;frame pointer
- movem.l A0-A2/A4/D0-D7,-(A7) ;save registers
-
- move.l #-1,D0 ;get link register
- bsr reg_a4 ;do it
- move.l 8(A6),D0 ;get byte address
- sub.l base(A4),D0 ;== logical address
-
- #ifdef SC_IMAGE
- move.l resolution(A4),D1 ;get scan line length
- #endif
-
- #ifdef NO_IMAGE
- move.l scrn_text(A4),D1 ;
- #endif
-
- divu D1,D0 ;== row number
- mulu D1,D0 ;== logical row start
- add.l base(A4),D0 ;== physical row start
- move.l D0,8(A6) ;put result on stack
-
- #ifdef NO_IMAGE
-
- movea.l one_line(A4),A1 ;get address line storage
- movea.l lines(A4),A0 ;get base of scanlen array
- move.l res_ix(A4),D6 ;scaled resolution ix
- /* >>> */
- move.l 0(A0,D6.w),D6 ;get size space
- bra clr_one_test ;go clear storage
-
- clr_one_loop:
- move.b #0,(A1)+ ;clear a byte
- clr_one_test:
- dbf D6,clr_one_loop ;go to end
-
- clr.l D6
- clr.l D5
- movea.l D0,A0 ;source address (screen)
- move.w xshift(A4),D5 ;shift count
- movea.l one_line(A4),A1 ;destination
- move.l #8,D0 ;8 scan lines unless high
-
- move.l res_ix(A4),D1 ;scaled resolution ix
- lsr.l #2,D1 ;unscale it
- dbf D1,j_not_low ;0 => low res
- bra low_just ;
- j_not_low:
- dbf D1,high_just ;1 => med res
- bra med_just
- high_just:
- move.l #16,D0 ;16 scan lines
-
- bsr save_high
- bra just_out
- med_just:
- bsr save_med
- bra just_out
- low_just:
- bsr save_low
- just_out:
- nop ;nothing
-
- #endif
-
- movem.l (A7)+,A0-A2/A4/D0-D7 ;restore registers
- unlk A6 ;deallocate frame
- rts ;and return
-
-
- /*****
- *
- * next_dline-- increment dumped string pointer.
- *
- * at entry:
- * no parms.
- *
- * at exit:
- * 'dump_string' contains pointer to next free string
- * space.
- *
- *
- *****/
- next_dline:
- movem.l D0/A0/A4,-(A7) ;save registers
-
- move.l #-1,D0 ;get link register
- bsr reg_a4 ;do it
-
- move.l #LINE_LEN,D0 ;get increment amount
- add.l D0,dump_string(A4) ;add it in
-
- movem.l (A7)+,D0/A0/A4 ;restore registers
- rts ;and return
-
-
- /*****
- *
- * reg_a4 -- use a trick to store Megamax C link registers in
- * code segment of program (i.e., without using base
- * address registers to access C data area).
- *
- * a4 is used to access external and static variables.
- * cf. the Megamax manual for more details.
- *
- * at entry:
- * d0 == 0 => save link register.
- * d0 != 0 => restore link register.
- *
- * at exit:
- * a4 is saved/restored, according to flag set at call.
- * a0 is destroyed.
- *
- *
- *****/
- reg_a4:
- bsr fix_a4 ;go save or retrieve link register
- save_a4:
- nop ;8 bytes' storage (4 more than needed)
- nop
- nop ;cordon sanitaire (safety first)
- nop
- fix_a4: move.l (A7)+,A0 ;get storage address
- tst.l D0 ;save or retrieve?
- beq store_a4 ;if former
- get_a4: movea.l (A0),A4 ;else get a4
- rts
- store_a4: move.l A4,(A0) ;save a4
- rts
-
-
- /****
- *
- * init_array-- initialize string array space with -1s.
- *
- * at entry:
- * a0 contains address of array base.
- * d0 contains size of array (in bytes).
- *
- * at exit:
- * all registers preserved.
- *
- * [26.II.86: written]
- *
- ****/
- init_array:
- movem.l A0/D0,-(A7) ;save registers
- bra.s i_a_test ;now start
- i_a_loop:
- move.b #-1,(A0)+ ;zero a byte
- i_a_test: dbf D0,i_a_loop ;go till end
- movem.l (A7)+,A0/D0 ;restore registers
- rts ;and return
-
-
- /*****
- *
- * print-- print string on screen.
- *
- *****/
- #ifdef TEST_VER
- print:
- link A6,#0 ;frame pointer
- movem.l A0-A2/D0-D2,-(A7) ;save registers
-
- move.l 8(A6),-(A7) ;pointer to string
- move.w #0x09,-(A7) ;code == print line
- trap #1 ;do it
- addq.l #6,A7 ;pop args
-
- movem.l (A7)+,A0-A2/D0-D2 ;restore registers
- unlk A6 ;deallocate frame
- rts ;return
-
- /*****
- *
- * keypress-- i.e., wait for one.
- *
- *****/
- keypress:
- movem.l A0-A2/D0-D2,-(A7) ;save registers
- move.w #1,-(A7) ;code == conin
- trap #1 ;do it
- addq.l #2,A7 ;pop arg
- movem.l (A7)+,A0-A2/D0-D2 ;restore registers
- rts ;return
-
- #endif
-
-
-
-
-
-