EASy68K
http://easy68k.com/EASy68Kforum/

need help with this code
http://easy68k.com/EASy68Kforum/viewtopic.php?f=7&t=1116
Page 1 of 1

Author:  Abdullah Rasheed [ Fri May 25, 2012 5:17 pm ]
Post subject:  need help with this code

i have the code of Digital Clock as i found it in the Esy68K Website.. i have changed the thickness of the time number ... but how can i change the color of the number, the background color.. add a voice as every hour pass .. please see this code

Code:
‎************************************************************************‎‎*************‎
‎*‎                                          ‎*‎
‎*‎   digital clock for the EASy68k simulator   ‎2004/4/4‎               ‎*‎



x_size   EQU   ‎80‎         ‎* x size in pixels‎
y_size   EQU   ‎160‎         ‎* y size‎

seg_thick   EQU   ‎16‎         ‎* segment thickness‎

dig_sep   EQU   x_size+10‎      ‎* one digit to the next‎
chr_sep   EQU   ‎2*dig_sep+40‎   ‎* hours to minutes, minutes to ‎seconds

x_pos      EQU   ‎10‎         ‎* top left x co-ordinate
y_pos      EQU   ‎10‎         ‎* top left y co-ordinate


‎************************************************************************‎‎*************‎
‎* code start. turn off the keyboard echo, set the initial colour and ‎draw the display
‎* this only needs to be done the once

   ORG      ‎$1000‎         ‎* set origin‎

start
   MOVEQ      ‎#12,d0‎      ‎* keyboard echo‎
   MOVEQ      ‎#0,d1‎         ‎* turn off echo‎
   TRAP      ‎#15‎         ‎* do i/o function‎

   BSR      LAB_init_disp   ‎* initialise display‎

   MOVEQ      ‎#8,d0‎         ‎* set for VFD colours‎
   MOVE.w   d0,LAB_colr      ‎* save it‎

‎* select next colour style. as there are only two entries in the colour ‎table we can
‎* toggle between them using a simple EOR instruction.‎

LAB_chgc
   MOVEQ      ‎#8,d0‎         ‎* set to toggle colours‎
   EOR.w      d0,LAB_colr      ‎* change colour array index

‎* either it's the first time through or the colour has just been changed ‎so set all
‎* the last time digits to $0A to force an update of all the clock digits ‎this time

   LEA      ‎(LAB_last,PC),a1‎   ‎* point to last time (seconds)‎
   MOVEQ      ‎#5,d7‎         ‎* six digits to do‎
   MOVEQ      ‎#$0A,d0‎      ‎* set for always update digit‎
LAB_clrl
   MOVE.b   d0,(a1)+‎      ‎* set digit‎
   DBRA      d7,LAB_clrl      ‎* loop‎

‎* main program loop starts here. first look to see if a key is waiting, ‎if there is
‎* get it and compare it with [SPACE]. if it's space then go and change ‎the colour
‎* index and force a whole display update‎

LAB_mainl
   MOVEQ      ‎#7,d0‎         ‎* get keyboard status‎
   TRAP      ‎#15‎
   TST.b      d1‎         ‎* test status‎
   BEQ.s      LAB_main      ‎* if no key waiting go do time‎

   MOVEQ      ‎#5,d0‎         ‎* get keyboard byte‎
   TRAP      ‎#15‎
   CMP.b      ‎#' ',d1‎      ‎* is it [SPACE]‎
   BEQ.s      LAB_chgc      ‎* if so go change the display colour‎

LAB_main
   MOVEQ      ‎#8,d0‎         ‎* get 100ths of a second since ‎midnight
   TRAP      ‎#15‎

‎* time in centiseconds since midnight is now in d1. first divide this by ‎‎100‎
‎* to give the time in seconds. to ensure that there is no overflow of ‎the
‎* divide instruction the longword time is split into words and each ‎handled
‎* separately‎

   MOVEQ      ‎#0,d0‎         ‎* clear longword‎
   SWAP      d1‎         ‎* switch words
   MOVE.w   d1,d0‎         ‎* copy time high word‎
   CLR.w      d1‎         ‎* clear high word‎

   MOVEQ      ‎#$64,d2‎      ‎* 100 decimal‎
   DIVU.w   d2,d0‎         ‎* divide high word‎
   SWAP      d0 ‎         ‎* switch words (remainder in low ‎word)‎
   MOVE.w   d0,d1‎         ‎* move remainder back‎
   SWAP      d0 ‎         ‎* switch words back (result in low ‎word)‎

   SWAP      d1‎         ‎* switch words‎
   DIVU.w   d2,d1‎         ‎* divide low word‎
   SWAP      d1‎         ‎* switch words (remainder in low ‎word)‎
   MOVE.w   d0,d1‎         ‎* copy seconds high word back‎
   SWAP      d1‎         ‎* switch words d1.l, now holds ‎seconds

‎* now divide the seconds up into the value for each digit. there is no ‎need to
‎* do this a word at a time as the first divide can never cause an ‎overflow. there
‎* are at most only 8368 tens of seconds in a day ‎

   LEA      ‎(LAB_curr,PC),a0‎   ‎* point to current time (seconds)‎
   MOVEQ      ‎#10,d0‎      ‎* divide by 10 for seconds‎
   BSR.s      LAB_digit      ‎* do digit‎
   MOVEQ      ‎#6,d0‎         ‎* divide by 6 for minutes‎
   BSR.s      LAB_digit      ‎* do digit‎
   MOVEQ      ‎#10,d0‎      ‎* divide by 10 for minutes‎
   BSR.s      LAB_digit      ‎* do digit‎
   MOVEQ      ‎#6,d0‎         ‎* divide by 6 for hours‎
   BSR.s      LAB_digit      ‎* do digit‎
   MOVEQ      ‎#10,d0‎      ‎* divide by 10 for hours‎
   BSR.s      LAB_digit      ‎* do digit‎
   MOVE.b   d1,(a0)‎      ‎* save 10s of hours digit‎

‎* the current time is now divided into digits and saved to memory. each ‎digit
‎* is compared to the same digit the last time here and if they differ ‎that
‎* digit is updated. at the first digit match the loop exits as all ‎remaining
‎* digits will be the same.‎

   LEA      ‎-5(a0),a0‎      ‎* reset current time pointer‎
   LEA      ‎(LAB_last,PC),a1‎   ‎* point to last time (seconds)‎

   MOVEQ      ‎#5,d7‎         ‎* six digits to do‎
LAB_displ
   MOVEQ      ‎#0,d0‎         ‎* clear longword‎
   MOVEQ      ‎#0,d1‎         ‎* clear longword‎
   MOVE.b   ‎(a0)+,d0‎      ‎* get new digit‎
   MOVE.b   ‎(a1),d1‎      ‎* get last digit‎

   CMP.b      d0,d1‎         ‎* compare digits‎
   BEQ.s      LAB_mainl      ‎* exit loop if no digit change‎

   MOVE.b   d0,(a1)+‎      ‎* else make last digit = new digit‎
   BSR.s      LAB_dispd      ‎* go update digit display‎
   DBRA      d7,LAB_displ   ‎* loop if more digits to check‎

   BRA.s      LAB_mainl      ‎* main loop‎


‎************************************************************************‎‎*************‎
‎* extract the next digit value from the time. this is easy on the 68k as ‎the DIVU
‎* instruction returns both the result of a divide and the remainder. in ‎this case
‎* the remainder is what we are interested in and is saved to the digit, ‎the divide
‎* result is just passed back‎

LAB_digit
   DIVU.w   d0,d1‎         ‎* divide for next digit‎
   SWAP      d1‎         ‎* remainder into low word‎
   MOVE.b   d1,(a0)+‎      ‎* save time digit‎
   CLR.w      d1‎         ‎* clear remainder
   SWAP ‎      d1‎         ‎* return the remaining time‎
   RTS


‎************************************************************************‎‎*************‎
‎* update the digit indexed by d7. first set up the pointers and indeces‎

LAB_dispd
   LEA      ‎(LAB_disp,PC),a4‎   ‎* point to colour table
   LEA      ‎(LAB_chr,PC),a3‎   ‎* point to character co-ordinates
   MOVE.w   d7,d6‎         ‎* copy digit index‎
   ADD.w      d6,d6‎         ‎* *2‎
   LEA      ‎(a3,d6.w),a3‎   ‎* get character co-ordinate pointer

‎* make two mask bytes, the first, in d4, has bits set for each segment ‎that needs
‎* to be 'turned on' and the second, in d5, has bits set for each segment ‎that
‎* needs to be turned off. this minimises the ammount of drawing that ‎needs to be
‎* done to change from the old digit to the new‎

   LEA      ‎(LAB_dig,PC),a2‎   ‎* point to segment map
   MOVE.b   ‎(a2,d0.w),d4‎   ‎* get new digit on map‎
   MOVE.b   ‎(a2,d1.w),d5‎   ‎* get old digit off map‎
   AND.b      ‎$0B(a2,d1.w),d4‎   ‎* make new on byte = not old & new‎
   AND.b      ‎$0B(a2,d0.w),d5‎   ‎* make new off byte = not new & old‎

‎* start at segment G and erase, draw or skip each segment as needed

   LEA      ‎(LAB_seg_x,PC),a2‎   ‎* point to segment displacements‎
   MOVEQ      ‎#6,d6‎         ‎* start at G segment‎
LAB_segl
   MOVE.w   LAB_colr,d3‎      ‎* get colour array index‎
   BTST      d6,d5‎         ‎* test segment off bit‎
   BEQ.s      LAB_nsegf      ‎* branch if no off bit‎

   MOVE.l   ‎(a4,d3.w),d1‎   ‎* else get erase colour‎
   BRA.s      LAB_segc      ‎* go erase the segment‎

LAB_nsegf
   BTST      d6,d4‎         ‎* test segment on bit‎
   BEQ.s      LAB_nsegn      ‎* branch if no on bit‎

   MOVE.l   ‎4(a4,d3.w),d1‎   ‎* else get draw colour
LAB_segc
   MOVEQ      ‎#81,d0‎      ‎* set fill colour for draw/erase‎
   TRAP      ‎#15‎

‎* the fill colour is set for this segment, now get a point from the ‎table that
‎* is somewhere within the segment and just flood fill it with the ‎previously set
‎* draw or erase colour

   MOVE.w   d6,d3‎         ‎* copy segment number‎
   ADD.w      d3,d3‎         ‎* *2 for word index‎
   MOVEQ   ‎#LAB_seg_y-LAB_seg_x,d2‎   ‎* offset to y table‎
   ADD.w      d3,d2‎         ‎* add index‎
   MOVE.w   ‎(a2,d3.w),d1‎   ‎* get segment x offset‎
   MOVE.w   ‎(a2,d2.w),d2‎   ‎* get segment y offset‎
   ADD.w      ‎(a3),d1‎      ‎* add digit x - set x co ordinate
   ADD.w      ‎#y_pos,d2‎      ‎* add digit y - set y co ordinate

   MOVEQ      ‎#89,d0‎      ‎* flood fill‎
   TRAP      ‎#15‎
LAB_nsegn
   DBRA      d6,LAB_segl      ‎* decrement & loop‎

   RTS


‎************************************************************************‎‎*************‎
‎* initialise the display. for each digit in turn a filled rectangle is ‎drawn then the
‎* segment outlines are drawn in the background colour. finally the upper ‎and lower
‎* voids are erased by filling them with the background colour

LAB_init_disp
   MOVEQ      ‎#5,d7‎         ‎* six digits to do‎

   MOVEQ      ‎#0,d1‎         ‎* set pen black‎
   MOVEQ      ‎#80,d0‎      ‎* set pen colour‎
   TRAP      ‎#15‎

   LEA      ‎(LAB_chr,PC),a3‎   ‎* point to character co-ordinates
LAB_initl
   MOVEQ      ‎#1,d1‎         ‎* set background colour
   MOVEQ      ‎#81,d0‎      ‎* set fill colour‎
   TRAP      ‎#15‎

‎* get the co-ordinates and draw the filled rectangle

   MOVE.w   d7,d6‎         ‎* copy digit index‎
   ADD.w      d6,d6‎         ‎* *2 for word table index‎

   MOVEQ      ‎#0,d1‎         ‎* clear x1 longword‎
   MOVEQ      ‎#0,d2‎         ‎* clear y1 longword

   MOVE.w   ‎(a3,d6.w),d1‎   ‎* set x1‎
   MOVE.w   ‎#y_pos,d2‎      ‎* set y1‎

   MOVE.l   d1,d3‎         ‎* copy x1‎
   MOVE.l   d2,d4‎         ‎* copy y1‎
   ADD.w      ‎#x_size,d3‎      ‎* calculate x2‎
   ADD.w      ‎#y_size,d4‎      ‎* calculate y2‎

   MOVEQ      ‎#87,d0‎      ‎* draw filled rectangle‎
   TRAP      ‎#15‎

‎* set the fill colour to the background colour so that any fills will ‎remove
‎* parts of the rectangle we just drew‎

   MOVEQ      ‎#0,d1‎         ‎* set black fill‎
   MOVEQ      ‎#81,d0‎      ‎* set fill colour‎
   TRAP      ‎#15‎

‎* the commands to draw the segment outlines are held in a table and are ‎stored as
‎* command, X co-ordinate, Y co-ordinate. using just the move, line and ‎fill graphics
‎* commands a whole range of shapes could be drawn‎

   LEA      ‎(LAB_outl,PC),a4‎   ‎* point to segment outline data‎
LAB_coml
   MOVE.w   ‎(a4)+,d0‎      ‎* get command‎
   BMI.s      LAB_comf      ‎* branch if commands finished‎

   MOVE.w   ‎(a4)+,d1‎      ‎* get next x1‎
   MOVE.w   ‎(a4)+,d2‎      ‎* get next y1‎
LAB_comd
   ADD.w      ‎(a3,d6.w),d1‎   ‎* add character offset x1‎
   ADD.w      ‎#y_pos,d2‎      ‎* add character offset y1‎
   TRAP      ‎#15‎

   BRA.s      LAB_coml      ‎* loop for next‎

LAB_comf
   DBRA      d7,LAB_initl   ‎* decrement & loop‎

   RTS


‎************************************************************************‎‎*************‎
‎* end of code, start of data‎

‎* data for segment outlines. first the G segment is outlined, then the A ‎and D
‎* segments are drawn and connecting lines are drawn between the corners ‎of these
‎* and the G segment to define the B, C, E and F segments. finally the ‎two inner
‎* voids are cleared with two fill commands‎

LAB_outl
   dc.w   ‎86,0,y_size/2‎               ‎* MOVE segment G‎
   dc.w   ‎85,seg_thick,y_size/2+seg_thick/2‎      ‎* LINE‎
   dc.w   ‎85,x_size-seg_thick,y_size/2+seg_thick/2‎   ‎* LINE‎
   dc.w   ‎85,x_size,y_size/2‎            ‎* LINE‎
   dc.w   ‎85,x_size-seg_thick,y_size/2-seg_thick/2‎   ‎* LINE‎
   dc.w   ‎85,seg_thick,y_size/2-seg_thick/2‎      ‎* LINE‎
   dc.w   ‎85,0,y_size/2‎               ‎* LINE‎

   dc.w   ‎86,0,0‎                  ‎* MOVE segment A‎
   dc.w   ‎85,seg_thick,seg_thick‎            ‎* LINE‎
   dc.w   ‎85,x_size-seg_thick,seg_thick         ‎* LINE‎
   dc.w   ‎85,x_size,0‎                  ‎* LINE‎

   dc.w   ‎86,0,y_size‎                  ‎* MOVE segment D
   dc.w   ‎85,seg_thick,y_size-seg_thick         ‎* LINE‎
   dc.w   ‎85,x_size-seg_thick,y_size-seg_thick   ‎* LINE‎
   dc.w   ‎85,x_size,y_size‎               ‎* LINE‎

   dc.w   ‎86,seg_thick,y_size/2-seg_thick/2‎      ‎* MOVE segment F‎
   dc.w   ‎85,seg_thick,seg_thick‎            ‎* LINE‎
   dc.w   ‎86,x_size-seg_thick,y_size/2-seg_thick/2‎   ‎* MOVE segment B‎
   dc.w   ‎85,x_size-seg_thick,seg_thick         ‎* LINE‎
   dc.w   ‎86,seg_thick,y_size/2+seg_thick/2‎      ‎* MOVE segment E‎
   dc.w   ‎85,seg_thick,y_size-seg_thick         ‎* LINE‎
   dc.w   ‎86,x_size-seg_thick,y_size/2+seg_thick/2‎   ‎* MOVE segment C
   dc.w   ‎85,x_size-seg_thick,y_size-seg_thick   ‎* LINE‎

   dc.w   ‎89,x_size/2,y_size/4‎            ‎* FILL upper void‎
   dc.w   ‎89,x_size/2,3*y_size/4‎            ‎* FILL lower void‎

   dc.w   ‎-1‎                     ‎* end marker‎


‎*‎   ‎  00000‎   segments A through G are represented by bits 0 through ‎‎6 as shown.‎
‎*‎   ‎ 5     1‎   the first line is the is the array of on segments, the ‎second line ‎
‎*‎   ‎ 5     1‎   is the array of off segments. an extra digit with all ‎it's segments
‎*‎   ‎  66666‎   both on and off is added to allow for a forced update ‎to the entire
‎*‎   ‎ 4     2‎   display, both at startup and when the colour is ‎changed
‎*‎   ‎ 4     2‎
‎*‎   ‎  33333‎   digits are 0 to 9 then the extra one in order

LAB_dig
   dc.b   ‎$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$7F‎
   dc.b   ‎$40,$F9,$A4,$B0,$99,$92,$82,$F8,$80,$90,$7F‎


‎* these tables define the top left corner of each digit. they are ‎calculated at
‎* assembly time from the values defined in the equates before the start ‎of the code
‎* only the x value is saved as the y value is the same for all digits‎

LAB_chr
   dc.w   x_pos
   dc.w   x_pos+dig_sep
   dc.w   x_pos+chr_sep
   dc.w   x_pos+chr_sep+dig_sep
   dc.w   x_pos+chr_sep+chr_sep
   dc.w   x_pos+chr_sep+chr_sep+dig_sep


‎* these two tables hold a list of points that lie one within each ‎segment. they
‎* are used as the flood fill origin points when painting the segments

LAB_seg_x
   dc.w   x_size/2‎         ‎* segment A‎
   dc.w   x_size-seg_thick/2‎   ‎* segment B‎
   dc.w   x_size-seg_thick/2‎   ‎* segment C‎
   dc.w   x_size/2‎         ‎* segment D‎
   dc.w   seg_thick/2‎         ‎* segment E‎
   dc.w   seg_thick/2‎         ‎* segment F‎
   dc.w   x_size/2‎         ‎* segment G‎
LAB_seg_y
   dc.w   seg_thick/2‎         ‎* segment A‎
   dc.w   y_size/4‎         ‎* segment B‎
   dc.w   ‎3*y_size/4‎         ‎* segment C‎
   dc.w   y_size-seg_thick/2‎   ‎* segment D‎
   dc.w   ‎3*y_size/4‎         ‎* segment E‎
   dc.w   y_size/4‎         ‎* segment F‎
   dc.w   y_size/2‎         ‎* segment G


‎* display colour table. these pairs of longwords are the unlit and lit ‎colours for
‎* the different styles of displays. note that neither of them can be the ‎same as the
‎* background colour as that is used to define the segment edges to bound ‎the flood
‎* fill‎

LAB_disp
   dc.l   ‎$111122,$1111FF‎      ‎* LED display‎
   dc.l   ‎$222211,$EEEE11‎      ‎* VF display‎


‎* variables‎

LAB_colr
   ds.w   ‎1‎            ‎* colour index word, 0 for LED, 8 ‎for VFD
LAB_curr
   ds.b   ‎6‎            ‎* current time, seconds to 10s hours‎
LAB_last
   ds.b   ‎6‎            ‎* last time, seconds to 10s hours‎


   END   start


‎************************************************************************‎‎*************‎

‎*~Font name~Courier New~‎
‎*~Font size~10~‎
‎*~Tab type~1~‎
‎*~Tab size~8~‎

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/