-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgameserverclient.s
More file actions
984 lines (889 loc) · 21.7 KB
/
gameserverclient.s
File metadata and controls
984 lines (889 loc) · 21.7 KB
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
;;apple game server client
;; (c) 2012, 2017 Egan Ford (egan@sense.net)
;; apple //e vectors
cout = $FDED ; character out
crout = $FD8E ; cr out
warm = $FF69 ; back to monitor
clear = $FC58 ; clear screen
movecur = $FB5B ; move cursor to ch,a
rdkey = $FD0C ; read key
bell = $FBDD ; ding
a80soff = $C000 ; page between main and main
a80sta = $C001 ; page between main and aux
a80off = $C00C ; 80 col mode on
a80on = $C00D ; 80 col mode on
altoff = $C00E ; alt char set off
alton = $C00F ; alt char set on
textoff = $C050 ; text mode off
texton = $C051 ; text mode on
hiresoff= $C056 ; hires off
mixedon = $C053 ; mixed mode lowres/text
mixedoff= $C052 ; mixed mode lowres/text off
mixed = $C01B ; mixed flag
page1on = $C054 ; page2off/page1on
page2on = $C055 ; page2on
setan3 = $C05E ; double lowres
clran3 = $C05F ; disable double lowres
auxmove = $C311 ; aux memory move
rstvecp = $03F2 ; reset vector pointer
;; my vectors
org = $800 ; my start
rstvec = $2D0 ; my reset vector code
;; zero page parameters
pointer = $00 ; pointer used for anything
current = $02 ; current title
counter = $03 ; generic counter
tmp = $03 ; generic counter
ptr = $04 ; pointer backup
gridx = $06 ; grid x end (row)
gridy = $07 ; grid y end (col)
wndleft = $21 ; window left
wndtop = $22 ; window top
ch = $24 ; cursor horizontal position
cv = $25 ; cursor verticle position
a1l = $3C ; auxmove source start low
a1h = $3D ; auxmove source start high
a2l = $3E ; auxmove source end low
a2h = $3F ; auxmove source end high
a4l = $42 ; auxmove dest low
a4h = $43 ; auxmove dest high
;; other vars
length = s002-s001 ; Length of titles
ttab = (40-length+1)/2 ; center of screen for titles
ttop = 5 ; top of scrolling window
downarrow= $8A
uparrow = $8B
returnkey= $8D
; Optional (recommend for c2t or DOS)
; DOS header location and size LSB/MSB
;.byte <start,>start,<(end-start),>(end-start)
.org org ; start here
;; setup reset vector
lda #<rstvec ; start of reset vector
sta rstvecp
lda #>rstvec
sta rstvecp+1
eor #$A5 ; something Apple //e needs as a check
sta rstvecp+2
;; copy main program to aux
lda #$00
sta a1l ; store source and dest low
sta a4l
lda #$08
sta a1h ; store source and dest high
sta a4h
lda #$FF
sta a2l ; store target high
lda #$87
sta a2h
sec ; copy from main to aux
jsr auxmove
ldx #0 ; copy maintoaux program to reset vector
setupvector:
lda maintoaux,x
sta rstvec,x
inx
cpx #maintoauxend-maintoaux
bne setupvector
jmp start ; start program
;; copy aux to main
maintoaux:
jsr clear ; clear screen if possible
lda #$00
sta a1l
sta a4l
lda #$08
sta a1h
sta a4h
lda #$FF
sta a2l
lda #$87
sta a2h
clc ; copy from main to aux
jsr auxmove
jmp start
maintoauxend:
start:
; copy tape code to high memory
ldx #0 ; this will get hosed on game load
moveit: ; as will just about everything else
lda tapecode,x ; in main memory
sta $BE00,x
lda tapecode+256,x
sta $BF00,x
inx
bne moveit
;; fresh start, clear screen, reset other settings
sta clran3 ; disable double lowres
sta mixedoff ; disable mixed
sta texton ; text mode on
sta a80off ; 40 col
sta a80soff ; page between main and main
sta page1on ; page one one
jsr clear ; clear screen
lda #40 ; set wndleft to 40 col
sta wndleft
;; print header
;jsr clear ; clear screen
sta alton ; use alt char set for lower case inverse
; center title
lda #19-(titleend-title-1)/2
sta ch ; sta hort. position
lda #<title ; load LSB of title:
ldy #>title ; load MSB of title:
jsr printinv ; print title:
jsr crout ; print CR
jsr crout ; print CR
; center instructions 1
lda #19-(ins1end-ins1-1)/2
sta ch ; sta hort. position
lda #<ins1 ; load LSB of ins1:
ldy #>ins1 ; load MSB of ins1:
jsr print ; print ins1:
jsr crout ; print CR
; center instructions 2
lda #19-(ins2end-ins2-1)/2
sta ch ; sta hort. position
lda #<ins2 ; load LSB of ins2:
ldy #>ins2 ; load MSB of ins2:
jsr print ; print ins2:
jsr crout ; print CR
;; print line
ldx #40 ; length of line
jsr line ; draw line
;; window setup
lda #ttop ; load 5 into A
sta wndtop ; set top of window for scrolling
;; print initial list
lda #<first ; set pointer to first item
sta pointer
lda #>first
sta pointer+1
;; print items
ldx #(24-ttop)
initloop:
jsr crout ; print CR
lda #ttab ; hort. tab for title center
sta ch ; store it
jsr print2 ; print item
;; inc pointer with length
clc ; clear carry flag
lda pointer ; load LSB of pointer
adc #length ; add length of titles
sta pointer ; store it
lda pointer+1 ; load MSB of pointer
adc #0 ; adc 0 + carry flag to MSB
sta pointer+1 ; store it
dex ; x=x-1
bne initloop ; if x != 0 goto initloop
;; reset pointer to first item
lda #<first ; set point to first item
sta pointer
lda #>first
sta pointer+1
lda #0 ; set current to first item
sta current ; current will be used to track the item
lda #5 ; set vert cursor position
sta cv ; cv will be used to track the bar
mainloop:
lda #ttab ; hort. tab for title center
sta ch ; sta hort. position
lda cv ; sta vert position
jsr movecur ; move cursor
jsr printinv2 ; highlight current item
;jsr rdkey ; get keyboard input
jsr getkey ; get keyboard input
ora #$80 ; just in case getkey returns $0x.
pha ; push key to stack
; clear light bar
lda #ttab ; hort. tab for title center
sta ch ; sta hort. position
jsr print2 ; un-highlight current item
pla ; pop key from stack
down:
cmp #downarrow ; down arrow
bne up ; check up: if not down
lda current ; load up current
; last item?
cmp #(last-first)/length
bne down1 ; last item, cannot go down
jmp none
down1:
inc current ; increment current position
;; do we go down or scroll screen
;; if current < (24-ttop)/2+1, then down
lda current ; load current item number
cmp #(24-ttop)/2+1 ; see if in of first 9 or so items
bcc down2 ; skip to down2 if so
;; if current > (last-first)/length - (24-ttop)/2 + 1, then down
; see if in bottom of last 9 or so items
cmp #((last-first)/length-(24-ttop)/2+1)
bcs down2 ; skip to down2 if so
;; else scroll up display
lda pointer ; backup pointer
sta ptr
lda pointer+1
sta ptr+1
; add 9 or so to pointer to display next line
clc ; clear carry flag
lda pointer ; load LSB of pointer
; add length of titles
adc #length*((24-ttop)/2+1)
sta pointer ; store it
lda pointer+1 ; load MSB of pointer
adc #0 ; adc 0 + carry flag to MSB
sta pointer+1 ; store it
lda #23 ; lda vert position to last line
jsr movecur ; move cursor
jsr crout ; print CR to scroll display
lda #ttab ; hort. tab for title center
sta ch ; sta hort. position
jsr print2 ; print item at bottom
lda ptr ; restore pointer
sta pointer
lda ptr+1
sta pointer+1
; put cv back - 1
lda #((24-ttop)/2 + ttop - 1)
sta cv ; maintain cv at middle of window
down2:
inc cv ; move verticle cursor down
; increment pointer
clc ; clear carry flag
lda pointer ; load LSB of pointer
adc #length ; add length of titles
sta pointer ; store it
lda pointer+1 ; load MSB of pointer
adc #0 ; adc 0 + carry flag to MSB
sta pointer+1 ; store it
jmp mainloop ; back to main loop
up:
cmp #uparrow ; up arrow
bne return ; check return: if not up
lda current ; load up current
beq none ; current zero?, then do nothing
dec current ; dec current position
;; do we go up or scroll screen
;; if current < (24-ttop)/2+1, then up
lda current ; load current item number
cmp #(24-ttop)/2+0 ; see if in of first 9 or so items
bcc up2 ; skip to up2 if so
;; if current > (last-first)/length - (24-ttop)/2 + 1, then up
; see if in bottom of last 9 or so items
cmp #((last-first)/length-(24-ttop)/2+0)
bcs up2 ; skip to up2 if so
;; else scroll down display
jsr scrolldown
;; print missing item
lda pointer ; backup pointer
sta ptr
lda pointer+1
sta ptr+1
; sub 9 or so to pointer to display next line
sec ; set carry flag
lda pointer ; load LSB of pointer
; add length of titles
sbc #length*((24-ttop)/2+1)
sta pointer ; store it
lda pointer+1 ; load MSB of pointer
sbc #0 ; sub 0 + carry flag to MSB
sta pointer+1 ; store it
lda #ttop ; lda vert position to last line
jsr movecur ; move cursor
lda #ttab ; hort. tab for title center
sta ch ; sta hort. position
jsr print2 ; print item at bottom
lda ptr ; restore pointer
sta pointer
lda ptr+1
sta pointer+1
; put cv back + 1
lda #((24-ttop)/2 + ttop + 1)
sta cv ; maintain cv at middle of window
up2:
dec cv ; move verticle cursor up
; dec pointer
sec ; set carry flag
lda pointer ; load LSB of pointer
sbc #length ; sub length of titles
sta pointer ; store it
lda pointer+1 ; load MSB of pointer
sbc #0 ; sub 0 - carry flag to MSB
sta pointer+1 ; store it
jmp mainloop ; back to main loop
return:
cmp #returnkey ; RETURN
bne none ; read another key if not RETURN
jmp done ; got RETURN, jump to done
none:
;; ring bell?
jsr bell
jmp mainloop
done:
;; take current pointer and do something with it
lda #0 ; load 0 into A
sta wndtop ; reset top of window
jsr clear ; clear screen
; double lores mode
sta textoff ; text mode off
sta hiresoff ; hires mode off
sta mixedon ; mixed graphics/text on
sta a80on ; 80 col mode on
sta setan3 ; double lowres
sta a80sta ; use main/aux for page1/page2
;; clear screen
sei ; disable interupts, enable after
; double lores fun
sta page1on ; turn on page1
jsr dlrclr ; double low res clear to white
sta page2on ; turn on page2
jsr dlrclr ; double low res clear to white
sta page1on ; turn on page1
lda #80 ; set wndleft to 80 col
sta wndleft
;; print help
lda #40-(ins3end-ins3)/2
sta ch ; sta hort. position
lda #21 ; move to line 21
jsr movecur ; move cursor
lda #<ins3 ; load LSB of ins3:
ldy #>ins3 ; load MSB of ins3:
;jsr print
jsr printinv80
lda #40-(ins4end-ins4)/2
sta ch ; sta hort. position
lda #22 ; move to line 22
jsr movecur ; move cursor
lda #<ins4 ; load LSB of ins4:
ldy #>ins4 ; load MSB of ins4:
;jsr print
jsr printinv80
;; print qrcode
lda #<qrptrl ; load up ptr to first 128 (0-127) qr codes
sta ptr
lda #>qrptrl
sta ptr+1
lda current ; check if current is > 127
bpl @1 ; if not then skip to @1:
lda #<qrptrh ; load up ptr to last qr codes
sta ptr
lda #>qrptrh
sta ptr+1
lda current ; check if current is > 127
and #$7F ; loose the high bit
@1:
asl ; times by 2 (we are scaning words)
tay ; copy A to Y
lda (ptr),y ; get address of qr code
sta qrptr+1 ; store in qrptr (self mod code--evil)
sta pointer ; need to get first byte for grid size
iny
lda (ptr),y
sta qrptr+2
sta pointer+1
;; setup x, y, gridx, gridy, for qr loop
ldy #0
lda (pointer),y ; grid size
sta gridx ; temp storage
lsr ; divide by 2
sta tmp ; use for temp storage
; for various reasons x will be use for Y axis and vv.
sec ; y coord start (cols)
lda #39 ; 39 or 40 for center of screen
sbc tmp ; - grid size / 2
sta starty+1 ; backup start of row location (self mod code)
tay ; Y start
sec ; x coord start (rows)
lda #23 ; 23 for center of screen
sbc tmp ; - grid size / 2
tax ; X start
tya ; compute grid y end
clc ; clear cary
adc gridx ; + grid size
sta gridy ; save it
txa ; compute grid x end
clc ; clear cary
adc gridx ; + grid size
sta gridx ; save it
lda #$80 ; set bit counter to last bit
sta counter
clc ; clear carry
;; main qr print loop
qrxloop: ; row loop
lda rowlo,x ; get row addr
sta ptr ; store in ptr
lda rowhi,x
sta ptr+1
qryloop: ; col loop
clc ; don't want to roll carry into counter
rol counter ; roll high bit into carry on first pass
bne nextbit ; if not 0 get next bit
nextbyte:
inc qrptr+1 ; inc LSB
bne rstcnt ; if not 0 (inc rollover) skip
inc qrptr+2 ; then inc MSB
rstcnt: lda #1 ; reset counter to 2^0
sta counter
nextbit:
qrptr: rol $FFFF ; X and Y will be in use (self mod code)
bcc nexty ; got 0
; got 1, print pixel
; is y even or odd? need to know for page
tya ; get (col)
ror ; put LS bit in to carry
bcs page1 ; odd number? skip to page1
sta page2on ; else enable page 2
bcc page2 ; skip over page 1 on
page1: sta page1on ; turn page 1 on
page2: ; divide col / 2
tya ; get (col)
pha ; back it up to stack
lsr ; divide / 2
tay ; copy to Y
; check x for odd/even
txa ; copy x to a
ror ; put LS bit in to carry
lda (ptr),y ; load up existing lores block
bcc even ; is x even
eor #$F0 ; x is odd, clear top 1/2 byte
bcs odd ; skip to odd
even: eor #$0F ; x is even, clear bottom 1/2 byte
odd: sta (ptr),y ; write to screen
pla ; retore old y (col) from stack
tay ; A->Y
nexty: iny ; y++
cpy gridy ; is y at right edge of grid?
bcc qryloop ; if not get next y pixel
; reset iny to start
starty: ldy #0 ; self mod code to retore y to col 0
inx ; x++, next row
cpx gridx ; is x at bottom edge of grid
bcc qrxloop ; if not move to next row of pixels
; qrcode done
cli ; enable interupts
;; all done, jmp to tape code
jmp $BE00
;; end of main program
dlrclr:
ldy #40 ; loop from 39 to 0
lda #$FF ; while top/bottom block
clearloop:
dey ; y--
sta $400,y ; lines 0,1
sta $480,y ; lines 2,3
sta $500,y ; lines 4,5
sta $580,y ; lines 6,7
sta $600,y ; lines 8,9
sta $680,y ; lines 10,11
sta $700,y
sta $780,y
sta $428,y
sta $4A8,y
sta $528,y
sta $5A8,y
sta $628,y
sta $6A8,y
sta $728,y
sta $7A8,y
sta $450,y
sta $4D0,y
sta $550,y
sta $5D0,y
bne clearloop
ldy #40 ; loop from 39 to 0
;lda #$A0 ; blankspace
lda #$20 ; blankspace
clearloop2:
dey ; y--
sta $650,y
sta $6D0,y
sta $750,y
sta $7D0,y
bne clearloop2
rts
line:
lda #'-'
ora #$80
loop0:
jsr cout
dex
bne loop0
rts
print:
sta pointer
sty pointer+1
print2:
ldy #0
lda (pointer),y ; load initial char
@lp: ora #$80
jsr cout
iny
lda (pointer),y
bne @lp
rts
printinv80:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
@lp: ora #$0
jsr cout
iny
lda (pointer),y
bne @lp
rts
printinv:
sta pointer
sty pointer+1
printinv2:
ldy #0
lda (pointer),y ; load initial char
@lp:
cmp #$60
bcs @sane
and #$3F
@sane:
jsr cout
iny
lda (pointer),y
bne @lp
rts
getkey: bit $C000
bpl getkey
lda $C010
rts
scrolldown:
ldy #ttab ; left site of items
scrollloop:
lda $750,y ; copy line 22 -> 23
sta $7D0,y
lda $6D0,y ; copy line 21 -> 22
sta $750,y
lda $650,y ; copy line 20 -> 21
sta $6D0,y
lda $5D0,y ; copy line 19 -> 20
sta $650,y
lda $550,y ; copy line 18 -> 19
sta $5D0,y
lda $4D0,y ; copy line 17 -> 18
sta $550,y
lda $450,y ; copy line 16 -> 17
sta $4D0,y
lda $7A8,y ; copy line 15 -> 16
sta $450,y
lda $728,y ; copy line 14 -> 15
sta $7A8,y
lda $6A8,y ; copy line 13 -> 14
sta $728,y
lda $628,y ; copy line 12 -> 13
sta $6A8,y
lda $5A8,y ; copy line 11 -> 12
sta $628,y
lda $528,y ; copy line 10 -> 11
sta $5A8,y
lda $4A8,y ; copy line 9 -> 10
sta $528,y
lda $428,y ; copy line 8 -> 9
sta $4A8,y
lda $780,y ; copy line 7 -> 8
sta $428,y
lda $700,y ; copy line 6 -> 7
sta $780,y
lda $680,y ; copy line 5 -> 6
sta $700,y
iny ; y++
; right side of items
cpy #(ttab+length-1)
bne scrollloop
rts
;; double lores addr table
rowlo: .byte $00,$00,$80,$80,$00,$00,$80,$80,$00,$00,$80,$80,$00,$00,$80,$80
.byte $28,$28,$A8,$A8,$28,$28,$A8,$A8,$28,$28,$A8,$A8,$28,$28,$A8,$A8
.byte $50,$50,$D0,$D0,$50,$50,$D0,$D0,$50,$50,$D0,$D0,$50,$50,$D0,$D0
rowhi: .byte $4,$4,$4,$4,$5,$5,$5,$5,$6,$6,$6,$6,$7,$7,$7,$7
.byte $4,$4,$4,$4,$5,$5,$5,$5,$6,$6,$6,$6,$7,$7,$7,$7
.byte $4,$4,$4,$4,$5,$5,$5,$5,$6,$6,$6,$6,$7,$7,$7,$7
;; string constants
title: .asciiz "Apple ][ Game Server Online! Client"
titleend:
ins1: .asciiz "UP/DOWN to select, RETURN to launch"
ins1end:
ins2: .asciiz "CTRL-RESET (or reboot) to return here"
ins2end:
ins3: .asciiz "Connect smartphone headphone jack to Apple //e cassette input jack (next to"
ins3end:
ins4: .asciiz "joystick port). Turn volume to max. Point QR scanner at screen."
ins4end:
;ins5: .asciiz "Visit http://asciiexpress.net/gameserver for more information."
;ins5end:
;; game titles
.include "titles.inc"
;; game qrcodes
.include "qrcodes.inc"
tapecode:
.scope tape
cout = $FDED ; character out sub
crout = $FD8E ; CR out sub
tapein = $C060 ; read tape interface
warm = $FF69 ; back to monitor
clear = $FC58 ; clear screen
inflate = $BA00 ; inflate code start
; zero page parameters
begload = $00 ; begin load location LSB/MSB
endload = $02 ; end load location LSB/MSB
chksum = $04 ; checksum location
remain = $04 ; checksum remainder location
pointer = $0C ; LSB/MSB pointer
inf_zp = $00 ; inflate code zero page vars (10)
.org $BE00
;jsr resetscreen ; back to 40 col mode
;jsr warm
getparams: ; client params
lda #<ld_beg ; store begin location LSB
sta begload
lda #>ld_beg ; store begin location MSB
sta begload+1
; end of params + 1 for checksum
lda #<end ; store end location LSB
sta endload
lda #>end ; store end location MSB
sta endload+1
retry:
jsr readtape ; get the code
;; new approach, check for error after rts
bne retry ; if readtape gets invalid length try again
; this is required in the event the smartphone
; QR scan app "dings" on detect
jsr resetscreen ; back to 40 col mode
lda #<param ; print param message
ldy #>param
jsr print
jsr sumcheck ; check the data
lda #<okm
ldy #>okm
jsr print
jsr crout ; 2 linefeeds
jsr crout
lda #<loadm ; print loading message
ldy #>loadm
jsr print
;; get the game
lda ld_beg ; store begin location LSB
sta begload
lda ld_beg+1 ; store begin location MSB
sta begload+1
; end of params + 1 for checksum
lda ld_end ; store end location LSB
sta endload
lda ld_end+1 ; store end location MSB
sta endload+1
jsr readtape ; get the code
beq dosum ; if readtape ok to load code branch to dosum
jmp error ; else jmp to error
dosum:
jsr sumcheck ; check the data
lda inf_flag ; if inf_flag = 0 runit
bne inf
jmp runit
inf:
jsr crout
lda #<infm
ldy #>infm
jsr print
lda inf_src ;src lsb
sta inf_zp+0
lda inf_src+1 ;src msb
sta inf_zp+1
lda inf_dst ;dst lsb
sta inf_zp+2
lda inf_dst+1 ;dst msb
sta inf_zp+3
jmp lastpage ;jump to page BF since inflate will kill BE
resetscreen:
sta clran3 ; disable double lowres
sta mixedoff ; disable mixed
sta texton ; text mode on
sta a80off ; 40 col
sta a80soff ; page between main and main
sta page1on ; page one one
jsr clear ; clear screen
lda #40 ; set wndleft to 40 col
sta wndleft
rts
readtape:
lda begload ; load begin LSB location
sta store+1 ; store it
lda begload+1 ; load begin MSB location
sta store+2 ; store it
ldx #0 ; set X to 0
lda #1 ; set A to 0
nsync: bit tapein ; 4 cycles, sync bit ; first pulse
bpl nsync ; 2 + 1 cycles
main: ldy #0 ; 2 set Y to 0
psync: bit tapein ;
bmi psync
ploop: iny ; 2 cycles
bit tapein ; 4 cycles
bpl ploop ; 2 +1 if branch, +1 if in another page
; total ~9 cycles
cpy #$40 ; 2 cycles if Y - $40 > 0 endcode (770Hz)
bpl endcode ; 2(3)
cpy #$15 ; 2 cycles if Y - $15 > 0 main (2000Hz)
bpl main ; 2(3)
cpy #$07 ; 2, if Y<, then clear carry, if Y>= set carry
store: rol store+1,x ; 7, roll carry bit into store
ldy #0 ; 2
asl ; 2 A*=2
bne main ; 2(3)
lda #1 ; 2
inx ; 2 cycles
bne main ; 2(3)
inc store+2 ; 6 cycles
jmp main ; 3 cycles
; 34 subtotal max
; 36 subtotal max
endcode:
txa ; write end of file location + 1
clc
adc store+1
sta store+1
bcc endcheck ; LSB didn't roll over to zero
inc store+2 ; did roll over to zero, inc MSB
endcheck: ; check for match of expected length
lda endload
cmp store+1
;bne error
bne enderror ; return and check for bne from caller
lda endload+1
cmp store+2
;bne error ; fix need to reset screen, etc...
enderror: ; return and check for bne from caller
rts ; return to caller
sumcheck:
sec ; set carry for sub operation
lda endload ; load end low
sbc begload ; sub beg load low with carry
sta remain ; save remainder
;tay ; y will be our number of byte starting
; with remainder of bytes to chksum
lda endload+1 ; load end high
sbc begload+1 ; sub beg load high with carry
tax ; x will be our number of 256 byte blocks
inx ; + 1
lda begload ; setup pointer low
sta pointer
lda begload+1 ; setup pointer high
sta pointer+1
dec pointer+1
lda #$ff ; init checksum
sumblockloop:
ldy #0
inc pointer+1
dex
bne sumloop
ldy remain ; load remainder
beq endsum ; 0?
remainder:
dey ; array base 0
eor (pointer),y
cpy #0
bne remainder
beq endsum
sumloop:
eor (pointer),y
iny
bne sumloop
beq sumblockloop
endsum:
;sumcheck:
; lda #0
; sta pointer
; lda begload+1
; sta pointer+1
; lda #$ff ; init checksum
; ldy begload
;sumloop:
; eor (pointer),y
; ;last page?
; ldx pointer+1
; cpx endload+1
; beq last
; iny
; bne sumloop
; inc pointer+1
; bne sumloop
;last:
; iny
; cpy endload
; bcc sumloop
sta chksum ; for debugging
lda chksum
bne sumerror ; chksum = 0?
rts ; return to caller
sumerror:
lda #<chkm
ldy #>chkm
jsr print
error:
bit mixed ; still in mixed mode?
bpl errorcont ; no then carry on
jsr resetscreen ; else reset screen first
errorcont:
lda #<errm
ldy #>errm
jsr print
jmp warm
ok:
lda #<okm
ldy #>okm
print:
sta pointer
sty pointer+1
ldy #0
lda (pointer),y ; load initial char
print1: ora #$80
jsr cout
iny
lda (pointer),y
bne print1
rts
lastpage:
jsr inflate ; decompress
lda inf_end ;dst end +1 lsb
cmp inf_zp+2
bne error
lda inf_end+1 ;dst end +1 msb
cmp inf_zp+3
bne error
runit:
lda warm_flag ; if warm_flag = 1 warm boot
bne warmit
jmp (runcode) ; run it
warmit:
jmp warm ; warm it
param: .asciiz "LOADING PARAMETERS "
chkm: .asciiz "CHKSUM "
okm: .asciiz "OK"
errm: .asciiz "ERROR"
infm: .byte $0D,"INFLATING ",$00
ld_beg:
.org *+2
ld_end:
.org *+2
inf_src:
.org *+2
runcode:
inf_dst:
.org *+2
inf_end:
.org *+2
inf_flag:
.org *+1
warm_flag:
.org *+1
loadm:
.org *+60
chk:
.org *+1
end:
.endscope