home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / magazi~1 / 226 / analog.49 / f7.ca < prev    next >
Encoding:
Text File  |  1986-10-14  |  16.0 KB  |  438 lines

  1. /*****************************************************************
  2. *
  3. * f7.ca:     more routines for ST text screen dump:
  4. *            part 2 of 3.
  5. *            Megamax in-line version.
  6. *
  7. *
  8. ******************************************************************/
  9.  
  10.  
  11. /****
  12. *
  13. * save_screen--  saves a block of memory (screen memory) so
  14. *                that we can then fool around with it with impunity
  15. *                (relatively speaking). 
  16. *
  17. *                The block is either the entire screen or a "window"
  18. *                   defined by variables set by 'set_window'.
  19. *
  20. *                It is assumed that the two blocks do not overlap.
  21. *
  22. *    at entry:
  23. *              (a6) +  8 ->   start of source block.
  24. *              (a6) + 12 ->   size of block (in words).
  25. *              (a6) + 16 ->   start of destination block.
  26. *              (a6) + 20 ->   resolution index.
  27. *
  28. *    at exit:
  29. *              all registers preserved.
  30. *
  31. *
  32. ****/
  33. #ifdef SC_IMAGE
  34. save_screen:
  35.           link           A6,#0               ;frame pointer
  36.           movem.l        A0-A2/A4/D0-D7,-(A7)   ;save registers
  37.  
  38.           move.l         #-1,D0              ;get a4
  39.           bsr            reg_a4              ;do it
  40.           clr.l          D6                  ;clear transfer register
  41.           clr.l          D5                  ;clear for word
  42.           move.w         xshift(A4),D5       ;get shift factor
  43.           movea.l        8(A6),A0            ;get source block start
  44.           move.l         12(A6),D0           ;size == count
  45.           movea.l        16(A6),A1           ;get dest block start    
  46.           move.l         20(A6),D1           ;resolution index
  47.           bne.s          s_sn_001            ;if not low res
  48.           bsr            save_low
  49.           bra            s_sn_003
  50. s_sn_001: subq.l         #1,D1               ;ix now == 0 or 1
  51.           dbf            D1,s_sn_002         ;if == 1, high res
  52.           bsr            save_med            ;else med res
  53.           bra            s_sn_003
  54. s_sn_002: bsr            save_high           ;high res save
  55.  
  56. s_sn_003:
  57.           movem.l        (A7)+,A0-A2/A4/D0-D7   ;restore registers
  58.           unlk           A6                  ;deallocate frame
  59.           rts                                ;return
  60. #endif
  61.  
  62. /****
  63. *
  64. * save_low--  save screen memory, 4 bit planes.
  65. * save_med--  save screen memory, 2 bit planes.
  66. * save_high-- save screen memory, 1 bit plane.
  67. *
  68. *    History tells us that the first bit planes were used in background
  69. *    shots during the filming of the "Battle of Britain". Since then many 
  70. *    more uses have been found for bit planes, particularly in computer
  71. *    architecture. Bit planes have been found to be particularly useful 
  72. *    in confusing computer programmers. Advanced computers are now often 
  73. *    found with several different bit-plane configurations, thus enabling
  74. *    them to confuse several programmers at the same time. Unfortunately,
  75. *    only one programmer worked on this project.
  76. *
  77. *    at entry:
  78. *              a0 == source block start.
  79. *              d0 == size of block in words.
  80. *              a1 == dest block start.
  81. *              d2 == length of line in bytes.
  82. *              d5 == shift factor for byte alignment.
  83. *              d7 == odd/even offset flag. (0xff => odd)
  84. *
  85. *    at exit:
  86. *              a0,a1,d0,d2-d6 destroyed.
  87. *              all other registers preserved.
  88. *
  89. *
  90. ****/
  91. save_high:
  92.           suba.l         back(A4),A0
  93.           bra            high_test
  94. high_loop:
  95.           adda.l         back(A4),A0         ;get to end of screen line
  96.           adda.l         front(A4),A0        ;get to start of window line
  97.           move.l         resolution(A4),D2   ;length of line in bytes
  98.           bra.s          line_h_test
  99. line_h:
  100.           /* this is the shift code for non-byte-aligned windows   */ 
  101.           move.b         (A0)+,D6            ;get "this" byte
  102.           lsl.w          #BYTESIZE,D6        ;shift it in register
  103.           move.b         (A0),D6             ;get next byte
  104.           lsl.w          D5,D6               ;align both 
  105.           lsr.w          #BYTESIZE,D6        ;now access low byte
  106.           move.b         D6,(A1)+            ;and save it
  107.  
  108. line_h_test:
  109.           dbf            D2,line_h           ;do one line
  110. high_test:
  111.           dbf            D0,high_loop        ;continue to end    
  112.           rts
  113.  
  114. /****
  115. ****/
  116. save_med:
  117.           clr.l          D7                  ;clear flag register
  118.           move.l         front(A4),D3        ;front offset
  119.           move.l         back(A4),D4         ;back offset
  120.           roxr.l         #1,D3               ;get low bit of 'front'
  121.           scs            D7                  ;set flag
  122.           andi.l         #-2,D4              ;make back offset even
  123.           lsl.l          #2,D3               ;re-align offset & double it
  124.           lsl.l          #1,D4               ;'back' * 2 too
  125.           suba.l         D4,A0               ;anticipate first loop
  126.           bra            med_test            ;start save
  127. med_loop:
  128.           adda.l         D4,A0               ;get to end of screen line
  129.           adda.l         D3,A0               ;get to start of window line
  130.           move.l         resolution(A4),D2   ;line length
  131.           tst.b          D7                  ;odd offset?
  132.           beq            line_m_test         ;if not
  133.           bra            line_modd           ;else start in mid of word
  134. line_m:
  135.           move.b         0(A0),D1            ;first plane
  136.           or.b           2(A0),D1            ;then second plane
  137.           lsl.w          #BYTESIZE,D1        ;move byte over
  138.           move.b         1(A0),D1            ;get next byte
  139.           or.b           3(A0),D1            ;and second plane
  140.           lsl.w          D5,D1               ;align data
  141.           lsr.w          #BYTESIZE,D1        ;recover first byte
  142.           move.b         D1,(A1)+            ;store data
  143. line_modd:
  144.           dbf            D2,line_mnxt        ;finished this line?
  145.           addq.l         #4,A0               ;if so, index to next
  146.           bra            med_test            ;and go
  147. line_mnxt:
  148.           move.b         1(A0),D1            ;else: 1st plane next group
  149.           or.b           3(A0),D1            ;get second
  150.           lsl.w          #BYTESIZE,D1        ;move byte over
  151.           move.b         4(A0),D1            ;get next byte
  152.           or.b           6(A0),D1            ;and second plane
  153.           lsl.w          D5,D1               ;align data
  154.           lsr.w          #BYTESIZE,D1        ;recover first byte
  155.           move.b         D1,(A1)+            ;save it
  156.           addq.l         #4,A0               ;index to next line
  157. line_m_test:
  158.           dbf            D2,line_m           ;finish line
  159. med_test:
  160.           dbf            D0,med_loop         ;continue to end
  161.           rts
  162.  
  163.  
  164. /****
  165. ****/
  166. save_low:
  167.           clr.l          D7                  ;clear flag register
  168.           move.l         front(A4),D3        ;front offset
  169.           move.l         back(A4),D4         ;back offset
  170.           roxr.l         #1,D3               ;get low bit of 'front'
  171.           scs            D7                  ;set flag
  172.           andi.l         #-2,D4              ;make back offset even
  173.           lsl.l          #3,D3               ; * 4 for 4 planes
  174.           lsl.l          #2,D4
  175.           suba.l         D4,A0               ;anticipate first loop
  176.           bra            low_test            ;start save
  177. low_loop:
  178.           adda.l         D4,A0               ;get to end of screen line
  179.           adda.l         D3,A0               ;get to start of window line
  180.           move.l         resolution(A4),D2   ;get line length
  181.           tst.b          D7                  ;odd offset?
  182.           beq            line_l_test         ;if not
  183.           bra            line_lodd           ;else start at odd byte            
  184.  
  185. line_l:
  186.           move.b         0(A0),D1            ;first plane
  187.           or.b           2(A0),D1            ;second plane
  188.           or.b           4(A0),D1            ;third plane
  189.           or.b           6(A0),D1            ;fourth plane
  190.           lsl.w          #BYTESIZE,D1
  191.           move.b         1(A0),D1
  192.           or.b           3(A0),D1
  193.           or.b           5(A0),D1
  194.           or.b           7(A0),D1
  195.           lsl.w          D5,D1
  196.           lsr.w          #BYTESIZE,D1
  197.           move.b         D1,(A1)+            ;store it
  198. line_lodd:
  199.           dbf            D2,line_lnxt        ;finished this line?
  200.           addq.l         #8,A0               ;next word-group
  201.           bra            low_test            ;if so
  202. line_lnxt:
  203.           move.b         1(A0),D1            ;now get next byte of data
  204.           or.b           3(A0),D1            ;and second plane
  205.           or.b           5(A0),D1            ;and third plane
  206.           or.b           7(A0),D1            ;and fourth plane
  207.           lsl.w          #BYTESIZE,D1
  208.           move.b         8(A0),D1
  209.           or.b           10(A0),D1
  210.           or.b           12(A0),D1
  211.           or.b           14(A0),D1
  212.           lsl.w          D5,D1
  213.           lsr.w          #BYTESIZE,D1
  214.           move.b         D1,(A1)+
  215.           addq.l         #8,A0
  216. line_l_test:
  217.           dbf            D2,line_l           ;finish line
  218. low_test:
  219.           dbf            D0,low_loop         ;continue to end
  220.           rts                                ;dummy comment
  221.  
  222.  
  223. /*****
  224. *
  225. * justify-- takes byte address in saved screen memory and returns
  226. *           the byte address of the beginning of the row in which 
  227. *           the original address lay.
  228. *           In NO_IMAGE version, also transfers a text line's worth
  229. *           of screen data into storage area, shifting the data if
  230. *           necessary to byte-align it. 
  231. *           Uses code in 'save_screen' (above).
  232. *
  233. *    at entry:
  234. *              (a6) + 8 ->    byte address.
  235. *
  236. *    at exit:  
  237. *              (a6) + 8 ->    justified address (i.e., result is
  238. *                             on stack).
  239. *
  240. *    if NO_IMAGE is defined, then the next text line of screen data
  241. *         is stored into 'one_line'.
  242. *
  243. *
  244. *****/
  245. justify:
  246.           link           A6,#0               ;frame pointer
  247.           movem.l        A0-A2/A4/D0-D7,-(A7)     ;save registers
  248.           
  249.           move.l         #-1,D0              ;get link register
  250.           bsr            reg_a4              ;do it
  251.           move.l         8(A6),D0            ;get byte address
  252.           sub.l          base(A4),D0         ;== logical address
  253.  
  254. #ifdef SC_IMAGE
  255.           move.l         resolution(A4),D1   ;get scan line length
  256. #endif
  257.  
  258. #ifdef NO_IMAGE
  259.           move.l         scrn_text(A4),D1    ;
  260. #endif
  261.  
  262.           divu           D1,D0               ;== row number
  263.           mulu           D1,D0               ;== logical row start
  264.           add.l          base(A4),D0         ;== physical row start
  265.           move.l         D0,8(A6)            ;put result on stack
  266.  
  267. #ifdef NO_IMAGE
  268.  
  269.           movea.l        one_line(A4),A1     ;get address line storage
  270.           movea.l        lines(A4),A0        ;get base of scanlen array
  271.           move.l         res_ix(A4),D6       ;scaled resolution ix
  272. /* >>> */
  273.           move.l         0(A0,D6.w),D6       ;get size space
  274.           bra            clr_one_test        ;go clear storage
  275.  
  276. clr_one_loop:
  277.           move.b         #0,(A1)+            ;clear a byte
  278. clr_one_test:
  279.           dbf            D6,clr_one_loop     ;go to end
  280.  
  281.           clr.l          D6
  282.           clr.l          D5
  283.           movea.l        D0,A0               ;source address (screen)
  284.           move.w         xshift(A4),D5       ;shift count
  285.           movea.l        one_line(A4),A1     ;destination
  286.           move.l         #8,D0               ;8 scan lines unless high
  287.  
  288.           move.l         res_ix(A4),D1       ;scaled resolution ix
  289.           lsr.l          #2,D1               ;unscale it
  290.           dbf            D1,j_not_low        ;0 => low res
  291.           bra            low_just            ;
  292. j_not_low:
  293.           dbf            D1,high_just        ;1 => med res
  294.           bra            med_just
  295. high_just:
  296.           move.l         #16,D0              ;16 scan lines
  297.           
  298.           bsr            save_high
  299.           bra            just_out
  300. med_just:
  301.           bsr            save_med
  302.           bra            just_out
  303. low_just:
  304.           bsr            save_low
  305. just_out:
  306.           nop                                ;nothing
  307.  
  308. #endif
  309.  
  310.           movem.l        (A7)+,A0-A2/A4/D0-D7     ;restore registers
  311.           unlk           A6                  ;deallocate frame
  312.           rts                                ;and return
  313.           
  314.  
  315. /*****
  316. *
  317. * next_dline-- increment dumped string pointer.
  318. *
  319. *    at entry:
  320. *              no parms.
  321. *
  322. *    at exit:
  323. *              'dump_string' contains pointer to next free string
  324. *                   space.
  325. *
  326. *
  327. *****/
  328. next_dline:
  329.           movem.l        D0/A0/A4,-(A7)      ;save registers
  330.  
  331.           move.l         #-1,D0              ;get link register
  332.           bsr            reg_a4              ;do it
  333.  
  334.           move.l         #LINE_LEN,D0        ;get increment amount
  335.           add.l          D0,dump_string(A4)  ;add it in
  336.  
  337.           movem.l        (A7)+,D0/A0/A4      ;restore registers
  338.           rts                                ;and return
  339.  
  340.  
  341. /*****
  342. *
  343. * reg_a4 --         use a trick to store Megamax C link registers in
  344. *                   code segment of program (i.e., without using base
  345. *                   address registers to access C data area).
  346. *
  347. *    a4 is used to access external and static variables.
  348. *    cf. the Megamax manual for more details.
  349. *    
  350. *    at entry:
  351. *              d0 == 0 => save link register.
  352. *              d0 != 0 => restore link register.
  353. *
  354. *    at exit:
  355. *              a4 is saved/restored, according to flag set at call.
  356. *              a0 is destroyed.
  357. *
  358. *
  359. *****/
  360. reg_a4:
  361.           bsr       fix_a4         ;go save or retrieve link register
  362. save_a4:
  363.           nop                      ;8 bytes' storage (4 more than needed)
  364.           nop
  365.           nop                      ;cordon sanitaire (safety first)
  366.           nop
  367. fix_a4:   move.l    (A7)+,A0       ;get storage address
  368.           tst.l     D0             ;save or retrieve?
  369.           beq       store_a4       ;if former
  370. get_a4:   movea.l   (A0),A4        ;else get a4
  371.           rts
  372. store_a4: move.l    A4,(A0)        ;save a4
  373.           rts
  374.  
  375.  
  376. /****
  377. *
  378. * init_array-- initialize string array space with -1s.
  379. *
  380. *    at entry:
  381. *              a0 contains address of array base.
  382. *              d0 contains size of array (in bytes).
  383. *
  384. *    at exit:
  385. *              all registers preserved.
  386. *
  387. *    [26.II.86:     written]
  388. *
  389. ****/
  390. init_array:
  391.           movem.l   A0/D0,-(A7)         ;save registers
  392.           bra.s     i_a_test            ;now start
  393. i_a_loop:
  394.           move.b    #-1,(A0)+           ;zero a byte
  395. i_a_test: dbf       D0,i_a_loop         ;go till end
  396.           movem.l   (A7)+,A0/D0         ;restore registers
  397.           rts                           ;and return
  398.  
  399.  
  400. /*****
  401. *
  402. * print-- print string on screen.
  403. *
  404. *****/
  405. #ifdef TEST_VER
  406. print:
  407.           link      A6,#0               ;frame pointer
  408.           movem.l   A0-A2/D0-D2,-(A7)   ;save registers
  409.  
  410.           move.l    8(A6),-(A7)         ;pointer to string
  411.           move.w    #0x09,-(A7)         ;code == print line
  412.           trap      #1                  ;do it
  413.           addq.l    #6,A7               ;pop args
  414.  
  415.           movem.l   (A7)+,A0-A2/D0-D2   ;restore registers
  416.           unlk      A6                  ;deallocate frame
  417.           rts                           ;return
  418.  
  419. /*****
  420. *
  421. * keypress-- i.e., wait for one.
  422. *
  423. *****/
  424. keypress:
  425.           movem.l   A0-A2/D0-D2,-(A7)   ;save registers
  426.           move.w    #1,-(A7)            ;code == conin
  427.           trap      #1                  ;do it
  428.           addq.l    #2,A7               ;pop arg
  429.           movem.l   (A7)+,A0-A2/D0-D2   ;restore registers
  430.           rts                           ;return
  431.  
  432. #endif
  433.  
  434.  
  435.  
  436.  
  437.          
  438.