The grayscale functions of Fargo consists of two simple functions in the file GRAYLIB.92P; One to turn on the grayscale display and return a pointer to the second bitplane, and one to turn it off again. The on-function just installs an interrupt routine on the 400hz counter that switches the bitplane every fourth time it is executed, which is exactly the same rate that is used for the LCD-refresh, 100hz. The planes is switched in such a way as to simulate three colors plus background instead of one plus background, using a cycle that is repeated every third time, like this:
Frame 1: Show Bitplane 0 Frame 2: Show Bitplane 0 Frame 3: Show Bitplane 1So the normal bitplane at adress $4440 is shown for 20ms and then the second bitplane is shown for 10ms. The whole cycle is then repeated every 30ms. So if we assume that the color intensity is directly proportional to the part of the 30ms cycle in which it is visible (wich seems reasonable) we will get the following intensities:
Color 0: 0.0 (Background, never shown) Color 1: 0.33 Color 2: 0.66 Color 3: 1.00This should give as an evenly spaced set of colors. This is not, however, the case. Color 1 is much closer to color 0 than color 2 and color 2 is very close to color 3. It's almost as if we needed a fifth color at intensity 0.5. I really don't know what's causing this effect, so please mail any ideas you might have about this.
Frame 1: Bitplane 0 Frame 2: Bitplane 1 Frame 3: Bitplane 0 Frame 4: Bitplane 2 Frame 5: Bitplane 0 Frame 6: Bitplane 1 Frame 7: Bitplane 0Which will give us an evened spaced intensity range like the one above. The problem here is that this cycle is much longer (17.5ms) and the flickering is getting pretty bad, especially if the sourrounding light is flickering at 50hz. Maybe we will have to stand 4 colors for now...
@program prog_code,prog_name
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;% Grayscale Example for Newbies - by Jonas Minnberg (Sasq) %
;% %
;% Since so many people on the FargoList asks about this, I %
;% put together a small example that you may use freely. %
;% It simply uses a pixelplot routine do draw horisontal %
;% lines in different colors. %
;% /Jonas Minnberg (md94-jmi@nada.kth.se) %
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;************** Start of Fargo program ***************
POS: dc.l 0 ;Holds X & Y position for next pixel to plot
prog_code:
jsr graylib[on] ;Turn on Grayscale display
move.l a6,plane2 ;Save pointer to second bitplane
move.w #959,d7 ;Clear second bitplane
\cloop0:
clr.l (a6)+ ;Slow clearing but who cares :)
dbf d7,\cloop0
move.w #959,d7 ;Clear first bitplane
lea $4440,a6
\cloop1:
clr.l (a6)+
dbf d7,\cloop1
moveq #0,d3 ;D3 Holds color number
lea POS(pc),a2 ;A2 Holds offset to coordinates
clr.l (a2) ;Start at (0,0)
moveq #127,d6 ;Loop index 1, 128 lines
\loop:
move.w #239,d7 ;Loop index 2, 240 rows
\loop2:
movem.w (a2),d0/d1 ;Put (X,Y) in DO & D1
bsr put_grayscale_pixel ;Call our pixelplot routine
add.w #1,(a2) ;Increase X coordinate
dbf d7,\loop2 ;Do the (Inner) Loop
clr.w (a2) ;Clear X coordinate and...
add.w #1,2(a2) ;increase Y coordinate
addq #1,d3 ;Also increase colorvalue
and.b #$03,d3 ;and make sure it's always 0-3
dbf d6,\loop ;Do the (Outer) Loop
jsr flib[idle_loop] ;Wait for a keypress
jsr graylib[off] ;And turn off grayscale display
rts
;D0.W = X position, D1.W = Y position, D3.B = Color (0-3)
put_grayscale_pixel:
move.w d0,d4
move.w d1,d5
lea $4440,a0 ;First bitplane
btst #1,d3 ;Test bit 1 in colorvalue to see if
beq.s \cpix0 ;we should set or clear this pixel
bsr set_pixel
bra.s \done0
\cpix0:
bsr clr_pixel
\done0:
move.w d4,d0
move.w d5,d1
move.l plane2(pc),a0 ;Second bitplane
btst #0,d3 ;Test bit 0 in colorvalue to see if
beq.s \cpix1 ;we should set or clear this pixel
bsr set_pixel
bra.s \done1
\cpix1:
bsr clr_pixel
\done1:
rts
;Clear Pixel
;A0.L = bitplane, D0.W = X position, D1.W = Y position
;Destroys D0-D2
clr_pixel:
bsr calc_offset
bclr.b d2,0(a0,d1)
rts
;Set Pixel
;A0.L = bitplane, D0.W = X position, D1.W = Y position
;Destroys D0-D2
set_pixel:
bsr calc_offset
bset.b d2,0(a0,d1)
rts
calc_offset:
add.w d1,d1 ;Multiply Y coordinate by 30
move.w d1,d2 ;without MUL instruction
lsl.w #4,d1 ;(32*Y-2*Y)
sub.w d2,d1 ;Only shifts and adds
move.b d0,d2
eor.b #$7,d2
lsr.b #3,d0
add.w d0,d1 ;D1 Now holds offset to byte
rts
plane2:
dc.l 0
prog_name:
dc.b "Grayscale example for Newbies",0
;*************** End of Fargo program ****************
reloc_open
add_library flib
add_library graylib
reloc_close
end
Written by Jonas Minnberg (Sasq / O2), md94-jmi@nada.kth.se