-
Notifications
You must be signed in to change notification settings - Fork 0
/
software_GOLD.psm
1254 lines (992 loc) · 44.3 KB
/
software_GOLD.psm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;============================================================================
;; File: software.psm
;; This a digital and analog clock display for 800x600 VGA for EE178 Lab #8.
;; By: Taylor Haddix, Ben Walker, Jay Patel, Jimmy Ta
;;============================================================================
;;============================================================================
;; Ports and related constants.
;;============================================================================
CONSTANT stax , 00 ; port for 8-bit start-x
CONSTANT stay , 01 ; port for 8-bit start-y
CONSTANT endx , 02 ; port for 8-bit end-x
CONSTANT endy , 03 ; port for 8-bit end-y
CONSTANT busy , 04 ; port for 8-bit busy
CONSTANT beam , 05 ; port for 8-bit beam
CONSTANT mode , 06 ; port for 8-bit mode
CONSTANT prng , 07 ; port for 8-bit prng
CONSTANT leds_lo , 08 ; port for 8-bit led data out
CONSTANT leds_hi , 09 ; port for 8-bit led data out
CONSTANT qssd_lo , 0a ; port for 8-bit qssd data out
CONSTANT qssd_hi , 0b ; port for 8-bit qssd data out
CONSTANT qssd_dp , 0c ; port for 8-bit qssd data out
CONSTANT switches_lo , 0d ; port for 8-bit switch input
CONSTANT switches_hi , 0e ; port for 8-bit switch input
CONSTANT buttons , 0f ; port for 8-bit button input
CONSTANT busy_go , 01 ; go command and busy status
CONSTANT beam_hi , 0f ; beam high intensity
CONSTANT beam_md , 07 ; beam med intensity
CONSTANT beam_lo , 03 ; beam low intensity
CONSTANT mode_hld , 00 ; mode hold framebuffer
CONSTANT mode_clr , 01 ; mode clear framebuffer
CONSTANT mode_lin , 02 ; mode linear decay
CONSTANT mode_exp , 03 ; mode exponential decay
CONSTANT button_ctr , 10 ; center
CONSTANT button_up , 08 ; up
CONSTANT button_dn , 04 ; down
CONSTANT button_left , 02 ; left
CONSTANT button_right , 01 ; right
;;============================================================================
;; system state declarations.
;;============================================================================
NAMEREG s0, system_state
CONSTANT state_zero, 00 ; 24 Hour Clock
CONSTANT state_one, 01 ; 12 Hour Clock
CONSTANT state_two, 02 ; Analog Clock
CONSTANT state_three, 03 ; Analog & Digital Clock
CONSTANT state_four, 04 ; Bouncing clock
CONSTANT state_five, 05 ; Jumping clock
NAMEREG s1, t_arc_second
NAMEREG s2, t_second
NAMEREG s3, t_minute
NAMEREG s4, t_hour
;;============================================================================
;; Global variables.
;;============================================================================
NAMEREG s5, display_digit
NAMEREG s6, line_pattern
NAMEREG s7, xpos ; for drawing routines
NAMEREG s8, ypos ; for drawing routines
NAMEREG s9, future_xpos ; for drawing routines
NAMEREG sA, future_ypos ; for drawing routines
NAMEREG sB, current_xpos ; for drawing routines
NAMEREG sC, loopvar ; for loops
NAMEREG sD, loopvar2 ; for loops
NAMEREG sE, scratch ; for scratch
NAMEREG sF, scratch2 ; for scratch
;;============================================================================
;; RAM ADDRESSES
;;============================================================================
CONSTANT hour_bcd, 01
CONSTANT hour_left, 02
CONSTANT hour_right, 03
CONSTANT hour_12_bcd, 04
CONSTANT hour_12_left, 05
CONSTANT hour_12_right, 06
CONSTANT minute_bcd, 07
CONSTANT minute_left, 08
CONSTANT minute_right, 09
CONSTANT second_bcd, 0A
CONSTANT second_left, 0B
CONSTANT second_right, 0C
CONSTANT sw_low_address, 0D ; switch lo RAM address
CONSTANT sw_high_address, 0E ; switch hi RAM address
CONSTANT button_flag, 0F
CONSTANT state_change_flag, 10
CONSTANT move_up_down, 11
CONSTANT move_left_right, 12
;;============================================================================
;; Other stuff.
;;============================================================================
CONSTANT minusone , ff ; minusone
CONSTANT minusmax , 80 ; minus 128
CONSTANT plusmax , 7f ; plus 127
CONSTANT zero , 00 ; zero
CONSTANT two , 02 ; two
CONSTANT one , 01 ; one
CONSTANT A_const, 13'd ;
CONSTANT M_const, 14'd ;
CONSTANT P_const, 15'd ;
CONSTANT colon_const, 16'd ;
;;============================================================================
;; Boot.
;; This performs one-time initialization of the hardware and state.
;;============================================================================
boot: CALL hw_init ; initial hardware setup
CALL cs_init ; set initial game state
ENABLE INTERRUPT ; enable vblnk interrupt
;;============================================================================
;; Main.
;; This is an empty loop, does nothing, waiting for interrupts to occur.
;;============================================================================
main: JUMP main ; empty loop, does nothing
;;============================================================================
;; Interrupt.
;; This is the main logic. At each interrupt, the procedure is to read
;; the user input, calculate the next state, and then draw the clock
;; state on the display.
;;============================================================================
isr: CALL count_time ; Increment timers
CALL debounce_at_200ms ; Every 30 arcseconds generate a debounce pulse
CALL calc_next_state ; Draw the state
RETURNI ENABLE ; return with enable
;;============================================================================
;; Subroutine: hw_init
;; This puts the hardware into a known, initial state. This includes a wait
;; to make sure the line drawing harware is idle (a wait loop which is also
;; called from other routines, as a subroutine).
;;============================================================================
hw_init: LOAD scratch, zero ; going to use lot of zero
OUTPUT scratch, leds_lo ; turn off lo leds
OUTPUT scratch, leds_hi ; turn off hi leds
LOAD scratch, zero ; going to use lot of zero
OUTPUT scratch, qssd_lo ; zeroize qssd lo
OUTPUT scratch, qssd_hi ; zeroize qssd hi
OUTPUT scratch, qssd_dp ; turn off qssd dots
LOAD scratch, mode_exp ;mode_exp ; load desired mode
OUTPUT scratch, mode ; program the framebuffer
LOAD scratch, beam_hi ; load desired beam
OUTPUT scratch, beam ; program the framebuffer
hw_init_wait: INPUT scratch, busy ; get framebuffer busy
COMPARE scratch, busy_go ; check framebuffer busy
JUMP Z, hw_init_wait ; back to wait if busy
RETURN ; return
;;============================================================================
;; Subroutine: cs_init
;; This puts the clock into a known, initial state.
;;============================================================================
cs_init: LOAD system_state, state_zero
LOAD t_arc_second, zero
LOAD t_second, zero
LOAD line_pattern, zero
LOAD t_minute, 25'd
LOAD t_hour, 2'd
LOAD scratch, zero
STORE scratch, move_up_down ;Set bouncing to go down first
RETURN ; return
;;============================================================================
;; Subroutine: calc_next_state
;; This uses the current state as input, and draws it on the display.
;; This logic calculates the next state of the clock, given the sampled user
;; inputs and the current state of the clock.
;;============================================================================
calc_next_state: COMPARE system_state, state_zero
JUMP Z, run_state_zero
COMPARE system_state, state_one
JUMP Z, run_state_one
COMPARE system_state, state_two
JUMP Z, run_state_two
COMPARE system_state, state_three
JUMP Z, run_state_three
COMPARE system_state, state_four
JUMP Z, run_state_four
COMPARE system_state, state_five
JUMP Z, run_state_five
RETURN
increment_state: COMPARE system_state, state_five
JUMP Z, reset_state
ADD system_state, 01
RETURN
reset_state: LOAD system_state, state_zero
RETURN
run_state_zero:
LOAD future_xpos, 88'd
LOAD future_ypos, 122'd
CALL qssd_show_hhmm
JUMP draw_vga_hhmmss
RETURN
run_state_one: LOAD future_xpos, 96'd
LOAD future_ypos, 122'd
CALL qssd_show_hhmm
JUMP draw_vga_hhmm
RETURN
run_state_two: CALL qssd_show_hhmm
JUMP draw_analog_clock
RETURN
run_state_three:CALL qssd_show_hhmm
LOAD future_xpos, 92'd
LOAD future_ypos, 172'd
CALL draw_vga_hhmmss
JUMP draw_analog_clock
RETURN
run_state_four: CALL qssd_show_ssff
CALL draw_vga_moving
RETURN
run_state_five: CALL qssd_show_ssff
CALL draw_vga_jumping
RETURN
;;============================================================================
;; Subroutine: LEDs
;; Controlls what is displayed on leds_lo and leds_hi
;;============================================================================
diagnostic_leds: OUTPUT t_second, leds_lo
OUTPUT t_minute, leds_hi
RETURN
;;============================================================================
;; Subroutine: analyze_user_input
;; Samples the user button presses to change system state, hours and minutes
;;============================================================================
analyze_user_input: LOAD scratch, zero ;; sample button hardware
INPUT scratch2, buttons ;; We are sampling scratch2
TEST scratch2, button_left ;Test left/right buttons
SUBCY scratch, zero
TEST scratch2, button_right
ADDCY scratch, zero
COMPARE scratch, minusone
CALL Z, user_left_btn
COMPARE scratch, one
CALL Z, user_right_btn
LOAD scratch, zero ; Clear scratch, then check up/dn
INPUT scratch2, buttons ;; We are sampling scratch2
TEST scratch2, button_up ;Test up/down buttons
SUBCY scratch, zero
TEST scratch2, button_dn
ADDCY scratch, zero
COMPARE scratch, minusone
CALL Z, user_up_btn
COMPARE scratch, one
CALL Z, user_up_btn
LOAD scratch, zero ;Test center button
TEST scratch2, button_ctr
ADDCY scratch, zero
COMPARE scratch, one
CALL Z, user_up_btn
RETURN
user_left_btn: CALL user_add_hour ; If button was pressed do action
RETURN
user_right_btn: CALL user_add_minute
RETURN
user_up_btn: CALL increment_state
RETURN
user_add_minute: ADD t_minute, 01 ; Count minutes until we reach 60
COMPARE t_minute, 60'd
CALL Z, user_reset_minute
RETURN
user_reset_minute: LOAD t_minute, 00 ; Count minutes until we reach 60
RETURN
user_add_hour: ADD t_hour, 01 ; Count minutes until we reach 24 hours
COMPARE t_hour, 24'd
CALL Z, user_reset_hour
RETURN
user_reset_hour: LOAD t_hour, 00 ; Count minutes until we reach 60
RETURN
;;======================================================================================================
;; Timing subroutines to keep track of hour, min, sec, arcseconds
;;
;;======================================================================================================
count_time: CALL time_into_ram ; Subroutine to count arc seconds (1/60th of a second)
ADD t_arc_second, 01 ; When 60 arcseconds have passed increment seconds counter
COMPARE t_arc_second, 60'd
CALL Z, time_add_second
RETURN
time_add_second: ADD t_second, 01 ; Count seconds until we reach 60
LOAD t_arc_second, 00 ; Then wrap back to 0, and reset arcseconds
COMPARE t_second, 60'd
CALL Z, time_add_minute
RETURN
time_add_minute: ADD t_minute, 01 ; Count minutes until we reach 60
LOAD t_second, 00 ; Then wrap back to 0, and reset seconds count
COMPARE t_minute, 60'd
CALL Z, time_add_hour
RETURN
time_add_hour: ADD t_hour, 01 ; Count minutes until we reach 24 hours
LOAD t_minute, 00 ; Then reset minutes and hour counter
COMPARE t_hour, 24'd
CALL Z, time_reset
RETURN
time_reset: LOAD t_hour, 00 ; Resets all time back to zero when finished with 24 cycle
LOAD t_second, 00
LOAD t_minute, 00
RETURN
;;============================================================================
;; Store the current time in RAM, In BCD format for 12 and 24 hour clock
;;============================================================================
time_into_ram: LOAD scratch, t_second ;Store time in BCD, and single digit the RAM
CALL byte_to_BCD ; By splitting binary into BCD
STORE scratch, second_bcd
LOAD scratch2, scratch ; Then isolating the upper and lower bytes
AND scratch, 0F
AND scratch2, F0
SR0 scratch2
SR0 scratch2
SR0 scratch2
SR0 scratch2
STORE scratch, second_right
STORE scratch2, second_left
LOAD scratch, t_minute ; Repeat RAM storage for minutes
CALL byte_to_BCD
STORE scratch, minute_bcd
LOAD scratch2, scratch
AND scratch, 0F
AND scratch2, F0
SR0 scratch2
SR0 scratch2
SR0 scratch2
SR0 scratch2
STORE scratch, minute_right
STORE scratch2, minute_left
LOAD scratch, t_hour ; Repeat RAM storage for hours
CALL byte_to_BCD
STORE scratch, hour_bcd
LOAD scratch2, scratch
AND scratch, 0F
AND scratch2, F0
SR0 scratch2
SR0 scratch2
SR0 scratch2
SR0 scratch2
STORE scratch, hour_right
STORE scratch2, hour_left
LOAD scratch, t_hour ; Repeat RAM storage for 12 hour clock
COMPARE scratch, 12'd
CALL NC, store_24hr_12hr
COMPARE scratch, 0'd
CALL Z, change_0_to_12
CALL byte_to_BCD
STORE scratch, hour_12_bcd
LOAD scratch2, scratch
AND scratch, 0F
AND scratch2, F0
SR0 scratch2
SR0 scratch2
SR0 scratch2
SR0 scratch2
STORE scratch, hour_12_right
STORE scratch2, hour_12_left
RETURN
change_0_to_12: ADD scratch, 12'd ; If in 12 hour format, make hour 0 display as 12
RETURN
store_24hr_12hr: SUB scratch, 12'd ; When storing time in RAM save a copy in 12 format
RETURN
;;============================================================================
;; Run Debouncing subroutine to check for user input, output diagnostics, and change screensaver
;;============================================================================
debounce_at_200ms: COMPARE t_arc_second, 0'd ; Count every 12 arcseconds to generate 200ms pulse
JUMP Z, run_debouncer
COMPARE t_arc_second, 12'd
JUMP Z, run_debouncer
COMPARE t_arc_second, 24'd
JUMP Z, run_debouncer
COMPARE t_arc_second, 36'd
JUMP Z, run_debouncer
COMPARE t_arc_second, 48'd
JUMP Z, run_debouncer
RETURN
run_debouncer: CALL analyze_user_input ; Debouncer checks for user input and sets diagnostic_leds
CALL diagnostic_leds
COMPARE system_state, state_four ; If screensaver is active, increase its position counter
RETURN NZ
CALL calculate_movement
RETURN
;;============================================================================
;; Quad 7-Segment Display
;; Outputs the time on the 7-segment displays
;;============================================================================
qssd_show_hhmm: FETCH scratch, hour_bcd
OUTPUT scratch, qssd_hi
FETCH scratch, minute_bcd
OUTPUT scratch, qssd_lo
FETCH scratch, second_right
OUTPUT scratch, qssd_dp
RETURN
qssd_show_mmss: FETCH scratch, minute_bcd
OUTPUT scratch, qssd_hi
FETCH scratch, second_bcd
OUTPUT scratch, qssd_lo
FETCH scratch, second_right
OUTPUT scratch, qssd_dp
RETURN
qssd_show_ssff: FETCH scratch, second_bcd
OUTPUT scratch, qssd_hi
OUTPUT t_arc_second, qssd_lo
FETCH scratch, minute_right
OUTPUT scratch, qssd_dp
RETURN
;;============================================================================
;; Format binary into BCD
;; Called by time_into_ram subroutine, feed it a scratch value it will modify scratch
;;============================================================================
byte_to_BCD: LOAD scratch2, 00 ;clear 'tens'
CALL b_to_d_loop
CALL nibbles_to_BCD
RETURN
b_to_d_loop: COMPARE scratch, 10'd ;if 'units' is less than 10
RETURN C ; then conversion complete
ADD scratch2, 1'd ;otherwise increment number of 'tens'
SUB scratch, 10'd ; and subtract 10 from 'units'
JUMP b_to_d_loop
nibbles_to_BCD:
sl0 scratch2
sl0 scratch2
sl0 scratch2
sl0 scratch2
OR scratch, scratch2 ;if 'units' is less than 10
RETURN
;;============================================================================
;; Table of digits stored as bitmaps
;; Users can input a digit and draw to any location
;;============================================================================
TABLE char_zero#, [00111100,01100110,01100110,11000011,11000011,11000011,11000011,11000011,11000011,01100110,01100110,00111100]'b
TABLE char_one#, [18,78,18,18,18,18,18,18,18,18,18,18]
TABLE char_two#, [3C,66,C3,03,03,06,0C,18,30,60,C0,FF]
TABLE char_three#, [3C,66,C3,03,06,1C,06,03,03,C3,66,3C]
TABLE char_four#, [06,0E,0E,1E,36,36,66,C6,FF,06,06,06]
TABLE char_five#, [FF,C0,C0,C0,FC,E6,03,03,03,C3,66,3C]
TABLE char_six#, [3C,66,C3,C0,FC,E6,C3,C3,C3,C3,66,3C]
TABLE char_seven#, [FF,03,03,06,06,06,0C,0C,0C,18,18,18]
TABLE char_eight#, [3C,66,C3,C3,66,3C,66,C3,C3,C3,66,3C]
TABLE char_nine#, [3C,66,C3,C3,C3,C3,67,3F,03,C3,66,3C]
TABLE char_colon#, [00,00,00,30,00,00,00,00,00,00,30,00]
TABLE char_A#, [00000000,00000000,00000000,00011000,00011000,00111100,00111100,01100110,01100110,01111110,11000011,11000011]'b
TABLE char_M#, [00000000,00000000,00000000,11000011,11000011,11100111,11100111,11111111,11111111,11011011,11011011,11000011]'b
TABLE char_P#, [00000000,00000000,00000000,01111110,01100011,01100011,01100011,01111110,01100000,01100000,01100000,01100000]'b
load_char_0: LOAD&RETURN line_pattern, char_zero#
load_char_1: LOAD&RETURN line_pattern, char_one#
load_char_2: LOAD&RETURN line_pattern, char_two#
load_char_3: LOAD&RETURN line_pattern, char_three#
load_char_4: LOAD&RETURN line_pattern, char_four#
load_char_5: LOAD&RETURN line_pattern, char_five#
load_char_6: LOAD&RETURN line_pattern, char_six#
load_char_7: LOAD&RETURN line_pattern, char_seven#
load_char_8: LOAD&RETURN line_pattern, char_eight#
load_char_9: LOAD&RETURN line_pattern, char_nine#
load_char_A: LOAD&RETURN line_pattern, char_A#
load_char_M: LOAD&RETURN line_pattern, char_M#
load_char_P: LOAD&RETURN line_pattern, char_P#
load_char_colon: LOAD&RETURN line_pattern, char_colon#
match_digit_to_char: LOAD line_pattern, loopvar ; This hold the current line pattern for the row
LOAD scratch, 00
LOAD scratch2, 00
; Make digit match here
COMPARE display_digit, 0'd
CALL Z, match_char_zero
COMPARE display_digit, 1'd
CALL Z, match_char_one
COMPARE display_digit, 2'd
CALL Z, match_char_two
COMPARE display_digit, 3'd
CALL Z, match_char_three
COMPARE display_digit, 4'd
CALL Z, match_char_four
COMPARE display_digit, 5'd
CALL Z, match_char_five
COMPARE display_digit, 6'd
CALL Z, match_char_six
COMPARE display_digit, 7'd
CALL Z, match_char_seven
COMPARE display_digit, 8'd
CALL Z, match_char_eight
COMPARE display_digit, 9'd
CALL Z, match_char_nine
COMPARE display_digit, A_const
CALL Z, match_char_A
COMPARE display_digit, M_const
CALL Z, match_char_M
COMPARE display_digit, P_const
CALL Z, match_char_P
COMPARE display_digit, colon_const
CALL Z, match_char_colon
RETURN
match_char_zero: LOAD scratch2, load_char_0'upper
LOAD scratch, load_char_0'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_one: LOAD scratch2, load_char_1'upper
LOAD scratch, load_char_1'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_two: LOAD scratch2, load_char_2'upper
LOAD scratch, load_char_2'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_three: LOAD scratch2, load_char_3'upper
LOAD scratch, load_char_3'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_four: LOAD scratch2, load_char_4'upper
LOAD scratch, load_char_4'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_five: LOAD scratch2, load_char_5'upper
LOAD scratch, load_char_5'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_six: LOAD scratch2, load_char_6'upper
LOAD scratch, load_char_6'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_seven: LOAD scratch2, load_char_7'upper
LOAD scratch, load_char_7'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_eight: LOAD scratch2, load_char_8'upper
LOAD scratch, load_char_8'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_nine: LOAD scratch2, load_char_9'upper
LOAD scratch, load_char_9'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_A: LOAD scratch2, load_char_A'upper
LOAD scratch, load_char_A'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_M: LOAD scratch2, load_char_M'upper
LOAD scratch, load_char_M'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_P: LOAD scratch2, load_char_P'upper
LOAD scratch, load_char_P'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
match_char_colon: LOAD scratch2, load_char_colon'upper
LOAD scratch, load_char_colon'lower
ADD scratch, line_pattern
ADDCY scratch2, 00
CALL@ (scratch2, scratch)
RETURN
;;============================================================================
;; Subroutine: Drawing algorithms select what is on the screen
;; Loop through the font bitmap and output the display
;;============================================================================
draw_while_loop_vert:
COMPARE loopvar, 12'd
JUMP Z, draw_while_loop_vert_end ; End loop when vertical loopvar ≥ 12 lines
CALL match_digit_to_char
LOAD loopvar2, 00
CALL draw_loop_horz
ADD loopvar, 01
JUMP draw_while_loop_vert
draw_while_loop_vert_end: RETURN
draw_loop_horz:
COMPARE loopvar2, 8'd
JUMP Z, draw_loop_horz_end ; End loop when horizontal loopvar2 ≥ 8 columns
TEST line_pattern, 10000000'b
CALL NZ, draw_dot ; // Matches 1 in the MSB, start drawing
ADD loopvar2, 01
sl0 line_pattern
JUMP draw_loop_horz
draw_loop_horz_end: RETURN
draw_dot: LOAD xpos, loopvar2
LOAD ypos, loopvar
ADD xpos, current_xpos
ADD xpos, future_xpos
ADD ypos, future_ypos
CALL moveto
CALL drawto
RETURN
;;============================================================================
;; Subroutine: moveto and drawto
;; The moveto routine uses the global variables xpos and ypos, and the drawto
;; routine uses these global variables as well as the endpoint coordinates in
;; the display controller. Moveto simply copies xpos and ypos into endpoint
;; coordinates in the display controller, it does not draw anything. The
;; drawto routine copies endpoint coordinates to startpoint coordinates (does
;; not matter if the endpoint was from an actual draw, or simply an update
;; by moveto) and then copies xpos and ypos into endpoint coordinates, then
;; starts a linedraw.
;;============================================================================
moveto: OUTPUT xpos, endx ; copy global to hardware
OUTPUT ypos, endy ; copy global to hardware
RETURN ; return
drawto: INPUT scratch, endx ; read hardware
OUTPUT scratch, stax ; write hardware
OUTPUT xpos, endx ; copy global to hardware
INPUT scratch, endy ; read hardware
OUTPUT scratch, stay ; write hardware
OUTPUT ypos, endy ; copy global to hardware
LOAD scratch, busy_go ; prepare the command
OUTPUT scratch, busy ; send the command
CALL hw_init_wait ; wait line draw done
RETURN ; return
;;============================================================================
;; Subroutine: Drawing states, Defines what you see on the display
;; During each of the different states
;;============================================================================
draw_vga_hhmmss: ADD current_xpos, 0'd
FETCH display_digit, hour_left ;;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, hour_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, colon_const ;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 7'd
FETCH display_digit, minute_left
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, minute_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, colon_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 7'd
FETCH display_digit, second_left
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, second_right ;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
LOAD current_xpos, 00
RETURN
draw_vga_hhmm:
ADD current_xpos, 0'd
FETCH display_digit, hour_12_left ;;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, hour_12_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, colon_const ;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 7'd
FETCH display_digit, minute_left
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, minute_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
COMPARE t_hour, 12'd
JUMP NC, draw_pm
JUMP draw_am
LOAD current_xpos, 00
RETURN
draw_am:
ADD current_xpos, 10'd
LOAD display_digit, A_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, M_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
LOAD current_xpos, 00
RETURN
draw_pm: ADD current_xpos, 10'd
LOAD display_digit, P_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, M_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
LOAD current_xpos, 00
RETURN
;;============================================================================
;; Subroutine: Draw moving clock
;;============================================================================
draw_vga_moving: ADD current_xpos, 0'd
FETCH display_digit, hour_12_left ;;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, hour_12_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, colon_const ;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 7'd
FETCH display_digit, minute_left
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, minute_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
LOAD display_digit, colon_const
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 7'd
FETCH display_digit, second_left
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, second_right ;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
COMPARE t_hour, 12'd
JUMP NC, draw_pm
JUMP draw_am
LOAD current_xpos, 00
RETURN
calculate_movement: FETCH scratch, move_left_right
COMPARE scratch, 00
CALL Z, go_right
COMPARE scratch, 01
CALL Z, go_left
FETCH scratch, move_up_down
COMPARE scratch, 00
CALL Z, go_up
COMPARE scratch, 01
CALL Z, go_down
RETURN
go_right: LOAD scratch, zero
STORE scratch, move_left_right
ADD future_xpos, 01
COMPARE future_xpos, 163'd
CALL NC, go_left
RETURN
go_left: LOAD scratch, one
STORE scratch, move_left_right
SUB future_xpos, 01
COMPARE future_xpos, 00
CALL Z, go_right
RETURN
go_up: LOAD scratch, zero
STORE scratch, move_up_down
ADD future_ypos, 01
COMPARE future_ypos, 244'd
CALL NC, go_down
RETURN
go_down: LOAD scratch, one
STORE scratch, move_up_down
SUB future_ypos, 01
COMPARE future_ypos, 00
CALL Z, go_up
RETURN
;;============================================================================
;; Subroutine: Draw Jumping Clock
;;============================================================================
draw_vga_jumping: FETCH scratch, second_right
COMPARE scratch, 3'd ; Once a second, do a random screen jump
CALL Z, do_next_jump
FETCH scratch, second_right
COMPARE scratch, 6'd ; Once a second, do a random screen jump
CALL Z, do_next_jump
FETCH scratch, second_right
COMPARE scratch, 9'd ; Once a second, do a random screen jump
CALL Z, do_next_jump
ADD current_xpos, 0'd
FETCH display_digit, hour_12_left ;;
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd
FETCH display_digit, hour_12_right
LOAD loopvar, 00 ;; These lines call the screen draw
CALL draw_while_loop_vert ;; Call after screen position and digit selected
ADD current_xpos, 10'd