Alive
News Team Current issue History Online Support Download Forum @Pouet

01 - 02 - SE - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14

Alive 10
Ooma Source Code

Alive is proud to present you the source code to "Ooma" the competition winning
bootsector from Outline 2005. You will be able to gather an exclusive insight
with comments by p01.

;      ##
;     # #   #######
;     # #  ##     #
;     ######  ### #
;   ### #  # #### #
;  #  ###  # ### ##
;  ####  ##  ## # #
;     #  #  #  # #
;    ####  # ####
;   ##    # ##   #
;  ##  ### ##  ####
;  #  #### #  #   #
;  # #### ## #  ###
;  # ### # # # #  #
;  #    # # ## # ##
;  #######   ######
; 
; ooma     bootsector
; 
; Mathieu 'P01' HENRI
; http://www.p01.org/
;
; #1 at Outline  2oo5


; commented source code released in
; the special edition of Alive


; notices:
;
; the sprites are in 16x16x2bpl and
; both have their own palette, thus
; each sprites takes 16*4+4*2 = 72b
;
; the rendering area is 256x160 big


; put some usefull addresses in
; a6 = palette
; a5 = ym2149
; a1 = current sprite index + zoom LUT
        move.w  #$8240,a6
        move.w  #$8800,a5
        move.w  #$200,a1

; start with sprite #0
        clr.l   -2(a1)

; sets the colour 15 to white
        not.w   30(a6)

; display the header
        pea     title(pc)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp

; set the current level of zoom
        clr.l   d0

; 15 is often used since the sprites are 16x16
        moveq   #15,d2
main_loop:

; decrease the zoom ratio
        sub.b   #4,d0
        bcc.s   no_carry

; move the center of the zoom
        add.b   #$47,-1(a1)

; swap the current sprite ( 72 or 0 )
        eori.w  #72,(a1)
no_carry:

; pick the current sprite -> a2
        lea     sprite(pc),a2
        adda.w  (a1),a2

; set the colors of the sprite
        move.l  (a2)+,(a6)
        move.l  (a2)+,4(a6)

; pick the zoomed position of the center
        move.l  d0,d1
        mulu.w  -2(a1),d1

; precalculate 256 consecutive zoomed
; positions and store them in 2(a1)
        move.w  #255,d7
precalc_scale:
        sub.w   d0,d1
        move.w  d1,d5
        lsr.w   #8,d5
        and.w   d2,d5

        move.b  d5,2(a1,d7.w)
        dbf     d7,precalc_scale

; precalculate the zoom for the 16 scanlines
; of the current sprite and store them in $600
        move.w  #$600,a3
        moveq   #60,d6
precalc_scanline_y:
; pick the long ( aka the current scanline ) of the sprite
        move.l  (a2,d6.w),d1

; calculate the zoomed scanlines of 256 pixels ( = 16 longs )
        move.w  #255,d7
        move.w  d2,d5

precalc_scanline_loop_x:
; pick the current zoomed position in
; the LUT computed in "precalc_scale:"
        move.b  2(a1,d7.w),d4

; test the corresponding bit on each
; of the 2bpl of the sprite and set it
; in our temporary long accordingly
        btst    d4,d1
        beq.s   firstBitplaneDone
        bset    d5,d3
firstBitplaneDone:

        swap    d1
        swap    d3
        btst    d4,d1
        beq.s   secondBitplaneDone
        bset    d5,d3
secondBitplaneDone:

        swap    d3
        swap    d1

; next pixel
        subq    #1,d5
        bpl.s   drawDone

; once 16 pixels are processed,
; we stack the long in $600
        move.l  d3,(a3)+
        moveq   #0,d3

drawDone:
        and.w   d2,d5
        dbf     d7,precalc_scanline_loop_x

; next scanline
        subq    #4,d6
        bpl.s   precalc_scanline_y


; pick the address of the screen, and shift to 32,20
; that is (160-256/2),(100-160/2)
        move.l  $44e.w,a0
        adda.w  #16080-64-80*160,a0

        move.w  #159,d6
loop_y:
; browse the LUT computed in "precalc_scale:"
; to pick the appropriate (pre)zoomed scanline
        moveq   #24,d1
        add.b   50(a1,d6.w),d1
        lsl.w   #6,d1
        move.w  d1,a3

; display the (pre)zoomed scanline
        move.w  d2,d7
loop_x:
        move.l  (a3)+,(a0)
        addq    #8,a0
        dbf     d7,loop_x

        adda.w  #32,a0

        dbf     d6,loop_y

music_rout:

; channel A = tone+noise
; channel B = tone
; channel C = mute
        move.w  #$7f4,d5
        movep   d5,(a5)

; get two pseudo random numbers
        move.w  $468.w,d5
        move.b  d0,d5
        lsr.w   #2,d5
        move.w  d5,d6
        lsr.w   #1,d6
        eori.b  #149,d6

        asr.w   #2,d5
        andi.b  #63,d5
        move.b  (a2,d5.w),d5
        eor.b   d6,d5

; Channel B fine tone
        move.b  #2,(a5)
        move.b  d5,2(a5)

; Channel B volume
        move.b  #9,(a5)
        eor.b   d2,d5
        move.b  d5,2(a5)

; Channel A fine tone
        movep   d6,(a5)

; Channel A rough tone
        move.w  #$104,d6
        movep.w d6,(a5)

; Channel A volume
        move.w  #$80b,d6
        movep.w d6,(a5)

        cmp.b   #57,$fffffc02.w
        bne     main_loop

kill_music:
; channels A,B,C = mute
        move.w  #$7ff,d5
        movep   d5,(a5)

; reset the 4 first and the 15th colors and exit
        move.l  #$07770700,(a6)+
        move.l  #$03450770,(a6)
        clr.w   26(a6)

        rts

title:
        dc.b    27,"Y",32+1,32+8,"ooma | p01 | Outline 2oo5",0
        even

sprite:
; Charly's pretty skin tones
        dc.l    $01010420,$06410762
; Hello Charly!
        dc.l    %01001111010011001100000001100011
        dc.l    %01010111100010001101000000000111
        dc.l    %11000111110011001001000000010011
        dc.l    %01001111111001111100000000000000
        dc.l    %10011111110110000100000000000000
        dc.l    %10101111110010100110000000011000
        dc.l    %00001111110000100000000000000000
        dc.l    %11111111111111110000000000000000
        dc.l    %00110111111100100000100000000000
        dc.l    %11011111111101011100001000000100
        dc.l    %01101111111100100100000000000101
        dc.l    %00101111111110101110010000000001
        dc.l    %11110011111110011001000000000000
        dc.l    %10011011111000110000100000000000
        dc.l    %10100111110011010000000000011110
        dc.l    %00011111100100101100000000100001

sprite2:
; Buzzy Bee deep tones
        dc.l    $01010013,$02360677
; Bzzz
        dc.l    %00001111000111000000000001000000
        dc.l    %11101111010110111110000001000011
        dc.l    %00001111000001100010000000000110
        dc.l    %00001000100001000010000000110100
        dc.l    %01000010001000000100011000110100
        dc.l    %10000000010000001010000011001100
        dc.l    %00011110000000000100000011011011
        dc.l    %00111100000001000000000000110110
        dc.l    %10011101100010011100000111101101
        dc.l    %00001011000000100000001100011011
        dc.l    %11001010000001001110001000010110
        dc.l    %00001010001001011000001000100101
        dc.l    %01001010010000010110001001010101
        dc.l    %00001010000010000100001110100001
        dc.l    %00001000000111000000000000000000
        dc.l    %11111111100111110000000000000000

p01 for Alive Diskmagazine, 2005-05-02


        
Alive 10