-
Notifications
You must be signed in to change notification settings - Fork 0
/
stnicc-beeb.asm
1315 lines (1073 loc) · 25.3 KB
/
stnicc-beeb.asm
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
\ -*- mode:beebasm -*-
\ ******************************************************************
\ * STNICC BEEB
\ ******************************************************************
_DEBUG = FALSE ; if you change me check the same in stnicc-build.asm
_TESTS = FALSE
; Display <drive no | sector no> <track no> <load to HI> <stream ptr HI>
_SHOW_STREAMING_INFO = FALSE
; If set, show total vsync count, rather than just the count for the
; last frame. Intended for use in conjunction with _STOP_AT_FRAME.
_SHOW_TOTAL_VSYNC_COUNTER = TRUE
_STOP_AT_FRAME = -1
; Debug defines
_DOUBLE_BUFFER = TRUE
_PLOT_WIREFRAME = FALSE
; Rendering defines
_HALF_VERTICAL_RES = (_QUALITY < 2)
_DOUBLE_PLOT_Y = (_QUALITY = 1)
_WIDESCREEN = (_QUALITY = 2) AND FALSE
_SKIP_ODD_FRAMES = FALSE
PRINT "------"
PRINT "STNICC-BEEB"
PRINT "------"
PRINT "_QUALITY =",_QUALITY
PRINT "_NULA =",_NULA
PRINT "_DEBUG =",_DEBUG
PRINT "_TESTS =",_TESTS
PRINT "_SHOW_STREAMING_INFO =",_SHOW_STREAMING_INFO
PRINT "_SHOW_TOTAL_VSYNC_COUNTER =",_SHOW_TOTAL_VSYNC_COUNTER
PRINT "_STOP_AT_FRAME =",_STOP_AT_FRAME
PRINT "_DOUBLE_BUFFER =",_DOUBLE_BUFFER
PRINT "_PLOT_WIREFRAME =",_PLOT_WIREFRAME
PRINT "_HALF_VERTICAL_RES =",_HALF_VERTICAL_RES
PRINT "_DOUBLE_PLOT_Y =",_DOUBLE_PLOT_Y
PRINT "_WIDESCREEN =",_WIDESCREEN
PRINT "------"
include "src/zp.h.asm"
include "src/music.h.asm"
\ ******************************************************************
\ * OS defines
\ ******************************************************************
osfile = &FFDD
oswrch = &FFEE
osasci = &FFE3
osbyte = &FFF4
osword = &FFF1
osfind = &FFCE
osgbpb = &FFD1
oscli = &FFF7
osargs = &FFDA
IRQ1V = &204
\\ Palette values for ULA
PAL_black = (0 EOR 7)
PAL_blue = (4 EOR 7)
PAL_red = (1 EOR 7)
PAL_magenta = (5 EOR 7)
PAL_green = (2 EOR 7)
PAL_cyan = (6 EOR 7)
PAL_yellow = (3 EOR 7)
PAL_white = (7 EOR 7)
ULA_Mode5 = &C4
ULA_Mode4 = &88
DFS_sector_size = 256
DFS_sectors_per_track = 10
DFS_track_size = (DFS_sectors_per_track * DFS_sector_size)
\ ******************************************************************
\ * MACROS
\ ******************************************************************
MACRO SWRAM_SELECT bank
LDA #bank: sta &f4: sta &fe30
ENDMACRO
if _NULA
MACRO MODE2_PIXELS a,b
equb ((-(a!=0))*%10101010) or ((-(b!=0))*%01010101)
ENDMACRO
endif
MACRO MODE5_PIXELS a,b,c,d
if _NULA
MODE2_PIXELS a,b
MODE2_PIXELS c,d
else
EQUB (a AND 2) * &40 OR (a AND 1) * &08 OR (b AND 2) * &20 OR (b AND 1) * &04 OR (c AND 2) * &10 OR (c AND 1) * &02 OR (d AND 2) * &08 OR (d AND 1) * &01
endif
ENDMACRO
MACRO PAGE_ALIGN
H%=P%
ALIGN &100
PRINT "Lost ", P%-H%, "bytes to PAGE alignment"
ENDMACRO
MACRO BOUNDARY_ALIGN b
skip b
PRINT "Lost ",b , "bytes to avoid crossing PAGE boundary"
ENDMACRO
MACRO PAGE_ALIGN_FOR_SIZE size
IF HI(P%+size) <> HI(P%)
PAGE_ALIGN
ENDIF
ENDMACRO
MACRO CHECK_SAME_PAGE_AS base
IF HI(P%-1) <> HI(base)
PRINT "WARNING! Table or branch base address",~base, "may cross page boundary at",~P%
ENDIF
ENDMACRO
\ ******************************************************************
\ * GLOBAL constants
\ ******************************************************************
; SCREEN constants
SCREEN_ROW_BYTES = 256
SCREEN_WIDTH_PIXELS = 128
SCREEN_HEIGHT_PIXELS = 200
SCREEN_SIZE_BYTES = (SCREEN_WIDTH_PIXELS * SCREEN_HEIGHT_PIXELS) / 4
WIDESCREEN_HEIGHT = 2 * SCREEN_WIDTH_PIXELS * 9 / 16
WIDESCREEN_TOP = (SCREEN_HEIGHT_PIXELS/2) - (WIDESCREEN_HEIGHT/2)
WIDESCREEN_BOTTOM = WIDESCREEN_TOP + WIDESCREEN_HEIGHT - 1
screen1_addr = &8000 - SCREEN_SIZE_BYTES
screen2_addr = screen1_addr - SCREEN_SIZE_BYTES
; STREAMING constants
STREAMING_tracks_per_disk = 79
STREAMING_sectors_to_load = 10
DISK1_drive_no = 0
DISK1_first_track = 30
DISK1_last_track = DISK1_first_track + 50
DISK2_first_track = 1
DISK2_last_track = DISK2_first_track + STREAMING_tracks_per_disk
STREAM_buffer_size = 3 * DFS_track_size
; STNICCC scene1.bin constants
MAX_VERTS_PER_POLY = 7
FLAG_CLEAR_SCREEN = 1
FLAG_CONTAINS_PALETTE = 2
FLAG_INDEXED_DATA = 4
POLY_DESC_END_OF_STREAM = &FD
POLY_DESC_SKIP_TO_64K = &FE
POLY_DESC_END_OF_FRAME = &FF
; Exact time for a 50Hz frame less latch load time
FramePeriod = 312*64-2
; This is when we trigger the next frame draw during the frame
; Essentially how much time we give the main loop to stream the next track
TimerValue = (12)*64 - 2*64
\ ******************************************************************
\ * ZERO PAGE
\ ******************************************************************
ORG &00
GUARD zp_top
.zp_start
.STREAM_ptr_LO skip 1
.STREAM_ptr_HI skip 1
; vars for plot_span
.writeptr skip 2
.span_start skip 1
;.span_end skip 1
.span_width skip 1
.span_colour skip 1
.shortptr skip 2
; vars for drawline
; loaded directly into X&Y
IF _DEBUG
.startx skip 1
.starty skip 1
ENDIF
.endx skip 1
.endy skip 1
.count skip 1
.accum skip 1
.scrn skip 2
.dx skip 1
.dy skip 1
.temp skip 1
; vars for plot_poly
.poly_num_verts skip 1
;.poly_colour skip 1
.poly_index skip 1
IF _HALF_VERTICAL_RES
.span_y skip 1
ELSE
.span_y \\ alias for poly_y
ENDIF
.poly_y skip 1
.poly_verts_x skip MAX_VERTS_PER_POLY+1
.poly_verts_y skip MAX_VERTS_PER_POLY+1
; vars for span_buffer
.span_buffer_min_y skip 1
.span_buffer_max_y skip 1
; frame parser
.frame_no skip 2
.frame_flags skip 1
; .frame_bitmask skip 2
.indexed_num_verts skip 1
;.poly_descriptor skip 1
.eof_flag skip 1
; palette vars
.pal_ptr_LO skip 1
.pal_ptr_HI skip 1
.pal_descriptor skip 1
.pal_byte1 skip 1
.pal_byte2 skip 1
.pal_dither_idx skip 1
; system vars
.rom_bank skip 1
.vsync_counter skip 2
.draw_buffer_HI skip 1
.sector_no skip 1
.track_no skip 1
.load_to_HI skip 1
.error_flag skip 1
.decode_lock skip 1
.screen_lock skip 1
.buffer_lock skip 1
; debug vars
IF _DEBUG
.pause_lock skip 1
.last_vsync skip 1
.debug_writeptr skip 2
ENDIF
.vsync_final skip 2
.clock_minutes skip 1
.clock_seconds skip 1
.clock_flashes skip 1
.char_def skip 9
.glyphptr skip 2
.glyphptr_copy skip 2
.music_enabled skip 1
.music_lock skip 1
.zp_end
\ ******************************************************************
\ * BSS DATA IN LOWER RAM
\ ******************************************************************
ORG &300
GUARD &800
.reloc_to_start
.screen_row_LO
skip &100
.screen1_row_HI
skip &100
.screen2_row_HI
skip &100
.y_to_row
skip &100
PAGE_ALIGN ; lazy
if not(_NULA)
.poly_palette
skip &40
.dither_table
skip &40
endif
.screen_col_LO
skip &80
.reloc_to_end
ORG &A00
GUARD &D00
.palette_stream_buffer ; or use &E00?
skip &300
ORG &E00
GUARD &1000
.span_buffer_start
skip &100
.span_buffer_end
skip &100
\ ******************************************************************
\ * CODE START
\ ******************************************************************
ORG &1100
GUARD screen2_addr
.start
.main_start
\ ******************************************************************
\ * Code entry
\ ******************************************************************
.main
{
\\ Init ZP
lda #0
tax
.zp_loop
sta &00, x
inx
cpx #zp_top
bne zp_loop
\\ Relocate data to lower RAM
lda #HI(reloc_from_start)
ldy #HI(reloc_to_start)
ldx #HI(reloc_to_end - reloc_to_start + &ff)
jsr copy_pages
if not(_NULA)
lda #HI(palette_stream_start)
ldy #HI(palette_stream_buffer)
ldx #HI(palette_stream_end - palette_stream_start + &ff)
jsr copy_pages
endif
\\ Set stream pointer
lda #LO(STREAM_buffer_start-1)
sta STREAM_ptr_LO
lda #HI(STREAM_buffer_start-1)
sta STREAM_ptr_HI
\\ Load our entire stream buffer from first track
LDA #DISK1_first_track
STA track_no
LDA #HI(STREAM_buffer_start)
STA load_to_HI
\\ Fill entire buffer
{
.loop
JSR load_next_track
LDA error_flag
BNE read_error
LDA load_to_HI
CMP #HI(STREAM_buffer_start) ; wrapped means buffer filled
BNE loop
.read_error
}
\\ Init early system
lda #HI(screen1_addr)
sta draw_buffer_HI
lda #LO(palette_stream_buffer-1)
sta pal_ptr_LO
lda #HI(palette_stream_buffer-1)
sta pal_ptr_HI
jsr init_span_buffer
\\ Init music
{
lda MUSIC_SLOT_ZP
bmi no_music
sta &f4:sta &fe30
jsr MUSIC_JUMP_INIT_MAIN
.no_music
}
\\ Setup video
jsr hide_screen
\\ Set ULA to MODE 5
lda #ULA_Mode5
sta &248 ; OS copy - OS interupt might be running..
sta &fe20
\\ Set CRTC to MODE 5 => 128x200
ldx #0
.crtc_loop
stx &fe00
lda mode5_crtc_regs, X
sta &fe01
inx
cpx #14
bcc crtc_loop
if _NULA
\\ Set NULA palette
lda #9:ldx #0:jsr osbyte
lda #10:ldx #0:jsr osbyte
lda #154:ldx #0:jsr osbyte
lda #$00
clc
.reset_palette_loop
pha
eor #$07:sta $fe21
pla
adc #$11
bcc reset_palette_loop
; disable NuLA auxiliary palette
lda #$10
sta $fe22
; set colour 0 to black
lda #$00
sta $fe23
sta $fe23
else
jsr set_palette
endif
\\ Clear all screens
jsr screen_clear_full
\\ Set interrupts and handler
SEI ; disable interupts
\\ Wait for vsync
jsr wait_for_vsync
\\ Not stable but close enough for our purposes
; Write T1 low now (the timer will not be written until you write the high byte)
LDA #LO(TimerValue):STA &FE44
; Get high byte ready so we can write it as quickly as possible at the right moment
LDX #HI(TimerValue):STX &FE45 ; start T1 counting ; 4c +1/2c
; Latch T1 to interupt exactly every 50Hz frame
LDA #LO(FramePeriod):STA &FE46
LDA #HI(FramePeriod):STA &FE47
LDA #&7F ; A=01111111
STA &FE4E ; R14=Interrupt Enable (disable all interrupts)
sta &fe6e ; User via
STA &FE43 ; R3=Data Direction Register "A" (set keyboard data direction)
LDA #&C2 ; A=11000010
STA &FE4E ; R14=Interrupt Enable (enable main_vsync and timer interrupt)
LDA IRQ1V:STA old_irqv
LDA IRQ1V+1:STA old_irqv+1
LDA #LO(irq_handler):STA IRQ1V
LDA #HI(irq_handler):STA IRQ1V+1 ; set interrupt handler
CLI ; enable interupts
\\ GO!
{
lda MUSIC_SLOT_ZP
bmi no_music
inc music_enabled
.no_music
}
jsr show_screen
.loop
\\ Debug
IF _DEBUG
{
lda pause_lock
beq continue
.wait_for_Key
lda #&79:ldx #&10:jsr osbyte:cpx #&ff:beq wait_for_Key
lda #0:sta pause_lock
.continue
}
ENDIF
lda eof_flag
cmp #POLY_DESC_END_OF_STREAM
beq track_load_error
\\ Which page are we reading crunched data from?
sec
lda STREAM_ptr_HI
\\ Is it more than a "track" away?
SBC load_to_HI
BCS sectors_to_load_1
EOR #255
ADC #1
.sectors_to_load_1
CMP #STREAMING_sectors_to_load
BCC not_ready_to_load
\\ If so, load a track's worth of data into our buffer
JSR load_next_track
\\ Unlock the buffer - there is some data!
lda #0:sta buffer_lock
.not_ready_to_load
\\ Check for errors
LDA error_flag
BEQ loop
.track_load_error
lda vsync_counter:sta vsync_final
lda vsync_counter+1:sta vsync_final+1
ldx #10:jsr wait_X_frames
jsr hide_screen
inc decode_lock ; stop decoder from running
jsr show_final_screen
\\ Turn off all interrupts
SEI
LDA #&7F
STA &FE4E ; R14=Interrupt Enable
LDA old_irqv:STA IRQ1V
LDA old_irqv+1:STA IRQ1V+1 ; set interrupt handler
CLI
{
lda MUSIC_SLOT_ZP
bmi no_music
sta &f4:sta &fe30
jsr MUSIC_JUMP_SN_RESET
.no_music
}
\\ Exit gracefully (in theory)
\\ Load next part
ldx #LO(next_part_cmd)
ldy #HI(next_part_cmd)
jmp oscli
}
.set_palette
\\ Set ULA palete for MODE 5
ldx #15
.pal_loop
lda mode5_palette, X
sta &fe21
dex
bpl pal_loop
rts
.show_screen
lda #&c0
equb &2c ; BIT abs
.hide_screen
lda #&f0
{
ldx #8:stx &fe00:sta &fe01 ; show the screen!
rts
}
IF _DEBUG
.show_vsync_counter
{
jsr debug_reset_writeptr
\\ Frame no.
lda frame_no+1
jsr debug_write_A
lda frame_no
jsr debug_write_A_spc
IF _SHOW_TOTAL_VSYNC_COUNTER
lda vsync_counter+1
jsr debug_write_A
lda vsync_counter+0
jsr debug_write_A_spc
ELSE
sec
lda vsync_counter
sbc last_vsync
jsr debug_write_A_spc
lda vsync_counter
sta last_vsync
ENDIF
IF _SHOW_STREAMING_INFO
lda osword_params_drive
asl a:asl a:asl a:asl a
ora osword_params_sector
jsr debug_write_A_spc
lda osword_params_track
jsr debug_write_A_spc
lda load_to_HI
jsr debug_write_A_spc
lda STREAM_ptr_HI
jsr debug_write_A_spc
ENDIF
{
lda frame_no+1
IF _STOP_AT_FRAME > -1
cmp #HI(_STOP_AT_FRAME)+1
bcs lock_me
ENDIF
cmp #HI(_STOP_AT_FRAME)
bcc continue
lda frame_no
cmp #LO(_STOP_AT_FRAME)
bcc continue
.lock_me
lda #&ff:sta pause_lock
.continue
}
rts
}
ENDIF
\ ******************************************************************
\ * Streaming tracks from disk
\ ******************************************************************
.load_next_track
{
\\ Track &FF indicates no more reading
LDA track_no
BMI TRACK_LOAD_return
\\ Store track no in params block
STA osword_params_track
LDA sector_no
STA osword_params_sector
\\ Update load address in params block
LDA load_to_HI
STA osword_params_address+1
\\ Make DFS read multi-sector call
LDX #LO(osword_params)
LDY #HI(osword_params)
LDA #&7F
JSR osword
\\ Error value returned at end of params block
LDA osword_params_return
STA error_flag
\\ Next track
CLC
LDA sector_no
.sectors_to_load_2
ADC #STREAMING_sectors_to_load
CMP #DFS_sectors_per_track
BCC same_track
SBC #DFS_sectors_per_track
INC track_no
.same_track
STA sector_no
\\ Which disk?
LDA osword_params_drive
BEQ TRACK_LOAD_disk_1 ; assumes we start on drive 0
\\ Disk N
LDA track_no
CMP #DISK2_last_track
BNE TRACK_LOAD_no_swap_disk
JMP TRACK_LOAD_disk_N
\\ Disk 1
.TRACK_LOAD_disk_1
LDA track_no
CMP #DISK1_last_track
BNE TRACK_LOAD_no_swap_disk
\\ Reached end of disk 1 so swap drives
.TRACK_LOAD_disk_N
LDX osword_params_drive
LDA drive_order, X
STA osword_params_drive
BNE TRACK_LOAD_continue
\\ End of last disk
\\ Reached end of disk N
LDA #&FF
STA track_no
BNE TRACK_LOAD_return
.TRACK_LOAD_continue
\\ Reset track to start of disk 2
LDA #DISK2_first_track
STA track_no
.TRACK_LOAD_no_swap_disk
\\ Increment our load ptr
CLC
LDA load_to_HI
.sectors_to_load_3
ADC #STREAMING_sectors_to_load
\\ Have we fallen off the end of the buffer?
CMP #HI(STREAM_buffer_end)
BNE TRACK_LOAD_no_wrap
\\ If so then reset to start
LDA #HI(STREAM_buffer_start)
.TRACK_LOAD_no_wrap
STA load_to_HI
.TRACK_LOAD_return
RTS
}
.irq_handler
{
LDA &FC
PHA
LDA &FE4D
AND #2
BEQ not_vsync
\\ Acknowledge vsync interrupt
STA &FE4D
lda #0
sta screen_lock
\\ Vsync
INC vsync_counter
BNE no_carry
INC vsync_counter+1
.no_carry
lda music_enabled
beq return_to_os
lda music_lock
bne return_to_os
inc music_lock
lda &f4:pha
lda MUSIC_SLOT_ZP
sta &f4:sta &fe30
txa:pha:tya:pha
jsr MUSIC_JUMP_VGM_UPDATE
pla:tay:pla:tax
pla:sta &f4:sta &fe30
dec music_lock
JMP return_to_os
.not_vsync
\\ Which interrupt?
LDA &FE4D
AND #&40 ; timer 1
BEQ return_to_os
\\ Acknowledge timer 1 interrupt
STA &FE4D
\\ If we're already busy just exit function
LDA decode_lock
\\ Can't start rendering as our frame buffer hasn't flipped
\\ Could start parse then block before touching the screen buffer
ora screen_lock
\\ Waiting for buffer fill
ora buffer_lock
IF _DEBUG
\\ Waiting for keypress
ora pause_lock
ENDIF
BNE return_to_os
\\ Set a lock on our decode function
INC decode_lock
\\ Store registers in case of interupts
TXA:PHA:TYA:PHA
\\ Do the slow bit!
{
\\ Decode the frame with interrupts off!
CLI
\\ Parse and draw the next frame
jsr parse_frame
sta eof_flag
cmp #POLY_DESC_END_OF_STREAM
bne not_eof
inc decode_lock ; lock us out of decoding the stream.
.not_eof
cmp #POLY_DESC_SKIP_TO_64K
bne stream_ok
\\ Align to start of streaming buffer (track size)
lda #LO(STREAM_buffer_start-1)
sta STREAM_ptr_LO
lda #HI(STREAM_buffer_start-1)
sta STREAM_ptr_HI
\\ Check whether we're still loading into the start of the streaming buffer
lda load_to_HI
cmp #HI(STREAM_buffer_start)
bne stream_ok
\\ We've caught our tail...
lda #&ff:sta buffer_lock
.stream_ok
IF _PLOT_WIREFRAME OR _SKIP_ODD_FRAMES
{
lda track_no
bmi enough_data_for_next_frame
lda STREAM_ptr_HI
cmp load_to_HI
bcs stream_ptr_gt_load_to
\\ Stream Ptr < Load To
sec
lda load_to_HI
sbc STREAM_ptr_HI
cmp #4
bcs enough_data_for_next_frame
\\ Otherwise lock our buffer
lda #&ff:sta buffer_lock
bne enough_data_for_next_frame
.stream_ptr_gt_load_to
\\ Stream Ptr > Load To
clc
lda load_to_HI
adc #HI(STREAM_buffer_size)
sec
sbc STREAM_ptr_HI
cmp #4
bcs enough_data_for_next_frame
\\ Otherwise lock our buffer
lda #&ff:sta buffer_lock
.enough_data_for_next_frame
}
ENDIF
if _NULA AND NOT(_DOUBLE_PLOT_Y)
ldy #219
ldx #0
.delay
inx
bne delay
iny
bne delay
endif
IF _DEBUG
jsr show_vsync_counter
ENDIF
\\ Disable interrupts again!
SEI
}
\\ Restore registers
PLA:TAY:PLA:TAX
\\ Remove our work lock
DEC decode_lock
IF _SKIP_ODD_FRAMES
lda frame_no
lsr a
bcs return_here_from_swap_frame_buffers
ENDIF
\\ Set our screen lock until frame swap
lda #&ff:sta screen_lock
\\ Swap frame buffers
jmp swap_frame_buffers
.^return_here_from_swap_frame_buffers
\\ Don't pass on to OS IRQ handler :)
.return_to_os
PLA
STA &FC
RTI
}
.old_irqv
EQUW &FFFF
; A=from page, Y=to page, X=number of pages
.copy_pages
{
sta read_from+2
sty write_to+2
ldy #0
.page_loop
.read_from
lda &ff00, Y
.write_to
sta &ff00, Y
iny
bne page_loop
inc read_from+2
inc write_to+2
dex
bne page_loop
rts
}
.swap_frame_buffers
{
\\ Toggle draw buffer
lda draw_buffer_HI
eor #HI(screen1_addr EOR screen2_addr)
sta draw_buffer_HI
\\ Set screen buffer address in CRTC - not read until vsync
cmp #HI(screen1_addr)
IF _DOUBLE_BUFFER
beq show_screen2
ELSE
bne show_screen2
ENDIF
\\ Show screen 1
lda #12:sta &fe00
lda #HI(screen1_addr/8):sta &fe01
lda #13:sta &fe00
lda #LO(screen1_addr/8):sta &fe01
\\ Draw screen 2
lda #HI(screen2_row_HI)
sta plot_long_span_set_screen+2
sta plot_short_span_set_screen+2
lda #LO(span_row_table_screen2_LO)
sta plot_span_set_row_table_LO+1
lda #HI(span_row_table_screen2_LO)
sta plot_span_set_row_table_LO+2
lda #LO(span_row_table_screen2_HI)
sta plot_span_set_row_table_HI+1
lda #HI(span_row_table_screen2_HI)
sta plot_span_set_row_table_HI+2
\\ Continue
bne continue
.show_screen2
\\ Show screen 2
lda #12:sta &fe00
lda #HI(screen2_addr/8):sta &fe01
lda #13:sta &fe00