Commit MetaInfo

Revision512f1467005ba4ef745fa857d684750e3bdf9017 (tree)
Time2020-01-01 09:08:19
Authoringlorion <homemicro@ingl...>
Commiteringlorion

Log Message

rom: friendly message after memcheck

Change Summary

Incremental Difference

diff -r e8f4e64a2b14 -r 512f1467005b rom/rom.s
--- a/rom/rom.s Tue Dec 31 08:40:04 2019 +0000
+++ b/rom/rom.s Wed Jan 01 00:08:19 2020 +0000
@@ -1,16 +1,35 @@
11 CURPOS = $80
2- FONTBASE = $e800
3- IOBASE = $d000
2+ BUFPTR = $82
3+ SHOWADDR = $84
4+ SHOWCTR = $86
5+ PUTINTAD = $fa
6+ PUTINTDG = $fb
7+ PUTINTPS = $fc
8+ SAVEA = $fd
9+ SAVEX = $fe
10+ SAVEY = $ff
411 IRQHNDLR = $0200
512 NMIHNDLR = $0204
613 RAMTOP = $021e
14+ KBDSTATE = $0220
15+ BUF = $0240
16+ IOBASE = $d000
17+ KBDCOL = $d002
18+ KBDROW = $d003
719 ROMBASE = $e000
20+ FONTBASE = $e800
821 SERIR = $d004
922 SERCR = $d005
1023
1124 * = ROMBASE
12- .byt $01, $00, $00
25+ ;; Feature bits.
26+ FEAT_HM1000 = $01
27+ FEATURES = FEAT_HM1000
28+ .byt FEATURES, $00, $00
29+
30+ ;; ROM function jump table.
1331 jmp cls
32+
1433 .dsb FONTBASE-*, $ff
1534 _charset:
1635 #include "8x8font.inc"
@@ -32,7 +51,11 @@
3251 lda #$ff
3352 ;; sta SERIR
3453 sta SERCR
35-
54+
55+ ;; Initialize constants.
56+ lda #>BUF
57+ sta BUFPTR + 1
58+
3659 ;; Memory check. First, we work work from $bfff down and write
3760 ;; #$aa to every address, until the value at $0220 has that value
3861 ;; or we reach $01ff (whichever comes first).
@@ -82,7 +105,7 @@
82105 stx $a1
83106 cpx #$c0
84107 bcc memcheck
85-
108+
86109 memcheck_done:
87110 tya
88111 sec
@@ -98,9 +121,14 @@
98121 sta IRQHNDLR
99122 sta NMIHNDLR
100123 cli
101-
124+
125+ jsr cls
126+ lda #1
127+ tax
128+ dex
129+ jsr setcur
130+
102131 ;; Show memcheck result in the bottom right corner of the screen.
103- jsr cls
104132 lda #$55
105133 sta $3f3d
106134 lda RAMTOP
@@ -108,6 +136,33 @@
108136 lda RAMTOP + 1
109137 sta $3f3f
110138
139+ ;; Also show as number.
140+ lda #<BUF
141+ sta BUFPTR
142+ lda #>BUF
143+ sta BUFPTR + 1
144+ lda RAMTOP
145+ sec
146+ adc #0
147+ sta $a0
148+ lda RAMTOP + 1
149+ adc #0
150+ sta $a1
151+ jsr showuint
152+ jsr showspc
153+ lda #<bytess
154+ sta SHOWADDR
155+ lda #>bytess
156+ sta SHOWADDR + 1
157+ lda #5
158+ sta SHOWCTR
159+ jsr show
160+ jsr showspc
161+ lda #$4f
162+ jsr showchr
163+ lda #$4b
164+ jsr showchr
165+
111166 lda #0
112167 sta $c0
113168 try_cart:
@@ -166,7 +221,7 @@
166221 lda #$aa
167222 sta $2007
168223 jmp ($c0)
169-
224+
170225 unloadable_image:
171226 lda #$80
172227 sta $2000
@@ -175,6 +230,22 @@
175230 sta $2003
176231 jmp _end
177232
233+adjcur:
234+;;; Scrolls so that the cursor position is within screen bounds.
235+ lda CURPOS + 1
236+ cmp #$3f
237+ bcc adjcurok
238+ bne adjcurscroll
239+ lda CURPOS
240+ cmp #$3f
241+ bcc adjcurok
242+adjcurscroll:
243+ lda #1
244+ jsr scrollup
245+ jmp adjcur
246+adjcurok:
247+ rts
248+
178249 loadcart:
179250 ;;; Loads data from a cartridge.
180251 ;;; In:
@@ -184,15 +255,15 @@
184255 ;;; Out:
185256 ;;; a 0 if successful. Any other value indicates an error.
186257 ;;; Clobbers x.
187- jsr twi_start
258+ jsr twistart
188259 jsr cart_set_location
189260 cmp #0
190261 bne loadcart_done
191- jsr twi_restart
262+ jsr twiresta
192263 cmp #0
193264 bne loadcart_done
194265 lda #$a1
195- jsr twi_send_byte
266+ jsr twisendb
196267 cmp #0
197268 bne loadcart_done
198269 dec $a4
@@ -200,10 +271,10 @@
200271 lda $a5
201272 beq loadcart_last
202273 loadcart_loop:
203- jsr twi_recv_byte
274+ jsr twigetb
204275 ldx #0
205276 sta ($a6,x)
206- jsr twi_ack
277+ jsr twiack
207278 inc $a6
208279 bne loadcart_skip_msb
209280 inc $a7
@@ -218,24 +289,24 @@
218289 bne loadcart_loop
219290 dec $a5
220291 jmp loadcart_loop
221-
292+
222293 loadcart_last:
223- jsr twi_recv_byte
294+ jsr twigetb
224295 ldx #0
225296 sta ($a6,x)
226- jsr twi_nak
297+ jsr twinak
227298 lda #0
228299
229300 loadcart_done:
230301 tax
231- jsr twi_stop
302+ jsr twistop
232303 txa
233304 rts
234305
235306 cart_set_location:
236307 ;;; Sets the location for the next cartridge operation.
237308 ;;; Preconditions:
238-;;; - twi_start must have been called.
309+;;; - twistart must have been called.
239310 ;;; In:
240311 ;;; $a0..$a3 Location to set.
241312 ;;; Out:
@@ -244,15 +315,15 @@
244315 lda $a2
245316 asl
246317 ora #$a0
247- jsr twi_send_byte
318+ jsr twisendb
248319 cmp #0
249320 bne cart_set_location_done
250321 lda $a1
251- jsr twi_send_byte
322+ jsr twisendb
252323 cmp #0
253324 bne cart_set_location_done
254325 lda $a0
255- jsr twi_send_byte
326+ jsr twisendb
256327 cart_set_location_done:
257328 rts
258329
@@ -279,25 +350,451 @@
279350 bcc cls_loop1
280351 rts
281352
282-twi_ack:
353+cmp16:
354+;;; Compares two 16-bit numbers.
355+;;; In:
356+;;; $a0..$a1 first number
357+;;; $a2..$a3 second
358+;;; Out:
359+;;; flags z if first == second
360+;;; c if first >= second
361+ lda $a0
362+ cmp $a2
363+ beq cmp16_eq
364+ lda $a1
365+ sbc $a3
366+ ora #2
367+ rts
368+cmp16_eq:
369+ lda $a1
370+ sbc $a3
371+ rts
372+
373+copy8:
374+;;; Copies 8 bytes from ($a2,3) to ($a0,1).
375+;;; Clobbers y.
376+ ldy #8
377+copy:
378+;;; Copies y bytes from ($a2,3) to ($a0,1).
379+ dey
380+ lda ($a2), y
381+ sta ($a0), y
382+ cpy #0
383+ bne copy
384+ rts
385+
386+putint:
387+ ;; In:
388+ ;; $a0..$a1 value to convert.
389+ ;; BUFPTR address to write next character to.
390+ ;; Out:
391+ ;; BUFPTR address one beyond the last written character.
392+ lda $a1
393+ bpl putuint
394+ ldy #0
395+ lda #$2d
396+ sta (BUFPTR), y
397+ inc BUFPTR
398+ sec
399+ lda #0
400+ sbc $a0
401+ sta $a0
402+ lda #0
403+ sbc $a1
404+ sta $a1
405+putuint:
406+ ;; In:
407+ ;; $a0..$a1 value to convert.
408+ ;; BUFPTR address to write next character to.
409+ ;; Out:
410+ ;; BUFPTR address one beyond the last written character.
411+ ;; Locals:
412+ ;; $a2..$a3 value we're currently comparing to.
413+ ;; PUTINTAD value to add to digit if test passes.
414+ ;; PUTINTDG value of current digit so far.
415+ ;; PUTINTPS position in uinttbl.
416+ ;;
417+ ;; The algorithm works like this:
418+ ;; $a2..$a3 goes through the sequence 40000, 20000, 10000,
419+ ;; 8000, 4000, 2000, 1000, 800, 400, 200, 100, 80, 40, 20, 10.
420+ ;; PUTINTAD tracks the first digit of this, so 4, 2, 1, 8, 4, 2, 1,
421+ ;; and so on.
422+ ;; PUTINTDG starts at 0.
423+ ;; On every iteration, we compare $a0..$a1 to $a2..$a3. If
424+ ;; $a0..$a1 is greater or equal, we subtract $a2..$a3 from it
425+ ;; and add PUTINTAD to PUTINTDG.
426+ ;; Every time PUTINTAD changes from 1 to 8, if PUTINTDG is not
427+ ;; equal to 0, we emit PUTINTDG and set it to #$30.
428+ ;;
429+ ;; For example, if the number we're converting is 60014, the
430+ ;; first steps are:
431+ ;; Compare 60014 to 40000. It's greater, so we subtract and
432+ ;; get 20014, and PUTINTDG becomes 4.
433+ ;; Compare 20014 to 20000. It's greater, so we subtract and
434+ ;; get 14, and PUTINTDG becomes 6.
435+ ;; Compare 14 and 10000. It's less, so we don't subtract and
436+ ;; don't change PUTINTDG.
437+ ;; Now PUTINTAD changes from 1 to 8, so we emit the 6 we have
438+ ;; accumulated in PUTINTDG and set PUTINTDG back to 0.
439+ ;; We compare to 8000, 4000, 2000, and 1000, and our number
440+ ;; is smaller in every case, so we end up emitting 0 for the
441+ ;; next digit. Same for the one one after that. Then we get to
442+ ;; 80, 40, 20, 10. In the last case, our number is greater, so
443+ ;; the digit we emit is 1, and the number we're left with is 4.
444+ ;; The last number, we just emit.
445+
446+ ;; Initialize local variables.
447+ lda uinttbl + 6
448+ sta $a2
449+ lda uinttbl + 7
450+ sta $a3
451+ lda #4
452+ sta PUTINTAD
453+ lda #0
454+ sta PUTINTDG
455+ lda #6
456+ sta PUTINTPS
457+putintl:
458+ jsr cmp16
459+ bcc putintlt
460+ jsr sub16
461+ lda PUTINTDG
462+ ora PUTINTAD
463+ sta PUTINTDG
464+putintlt:
465+ lsr PUTINTAD
466+ beq putintdg
467+ lsr $a3
468+ ror $a2
469+ bcc putintl ; always taken
470+putintdg:
471+ ldy #0
472+ lda PUTINTDG
473+ beq putintsk
474+ ora #$30
475+ sta (BUFPTR), y
476+ inc BUFPTR
477+ lda #$30
478+ sta PUTINTDG
479+putintsk:
480+ dec PUTINTPS
481+ dec PUTINTPS
482+ bmi putintls
483+ ldy PUTINTPS
484+ lda uinttbl, y
485+ sta $a2
486+ iny
487+ lda uinttbl, y
488+ sta $a3
489+ lda #8
490+ sta PUTINTAD
491+ bpl putintl ; always taken
492+putintls:
493+ lda $a0
494+ ora #$30
495+ sta (BUFPTR), y
496+ inc BUFPTR
497+ rts
498+
499+qkbrow:
500+;;; Queries a keyboard row.
501+;;; In:
502+;;; a keyboard row to query (mask with one bit clear, others set)
503+;;; Out:
504+;;; a state of keyboard row
505+ sta KBDROW
506+ nop
507+ lda KBDCOL
508+ rts
509+
510+sub16:
511+ sec
512+sbc16:
513+;;; Subtracts two 16-bit numbers.
514+;;; In:
515+;;; $a0..$a1 first number
516+;;; $a2..$a3 second
517+;;; Out:
518+;;; $a0..$a result
519+;;; flags c if first >= second
520+ lda $a0
521+ sbc $a2
522+ sta $a0
523+ lda $a1
524+ sbc $a3
525+ sta $a1
526+ rts
527+
528+scrollup:
529+;;; Scrolls the screen up a lines.
530+ ;; a * 320 + #$2000 in $a2..$a3.
531+ ;; #$2000 in $a0..$a1.
532+ sta $a3
533+ ldy #0
534+ sty $a2
535+ sty $a0
536+ lsr
537+ ror $a2
538+ lsr
539+ ror $a2
540+ clc
541+ adc $a3
542+ adc #$20
543+ sta $a3
544+ lda #$20
545+ sta $a1
546+ ;; update CURPOS
547+ lda CURPOS
548+ sec
549+ sbc $a2
550+ sta CURPOS
551+ lda CURPOS + 1
552+ sbc $a3
553+ bcs scrollupcpok
554+ lda #0
555+ sta CURPOS
556+scrollupcpok:
557+ clc
558+ adc #$20
559+ sta CURPOS + 1
560+ ;; copy bytes until $a2..$a3 > #$3f3f.
561+scrolluplow:
562+ lda $a3
563+ cmp #$3f
564+ bcs scrolluphi
565+ ;; y is 0 at this point
566+scrollupll:
567+ lda ($a2), y
568+ sta ($a0), y
569+ iny
570+ bne scrollupll
571+ inc $a1
572+ inc $a3
573+ jmp scrolluplow
574+scrolluphi:
575+ bne scrollupblank
576+ clc
577+scrolluphl:
578+ tya
579+ adc $a2
580+ cmp #$40
581+ bcs scrollupblank
582+ lda ($a2), y
583+ sta ($a0), y
584+ iny
585+ jmp scrolluphl
586+scrollupblank:
587+ lda $a1
588+ cmp #$3f
589+ bcc scrollupmore
590+ bne scrollupdone
591+ lda $a0
592+ bne scrollupdone
593+ lda #$3e
594+ sta $a1
595+ lda #$40
596+ sta $a0
597+ ldy #$c0
598+scrollupmore:
599+ lda #0
600+ sta ($a0), y
601+ iny
602+ bne scrollupmore
603+ inc $a1
604+ jmp scrollupblank
605+scrollupdone:
606+ rts
607+
608+setcur:
609+;;; Sets the cursor position.
610+;;; In:
611+;;; a Row (0..24).
612+;;; x Column (0..39).
613+ ;; We need 320 * row + 8 * col.
614+ ;; = 256 * row + 64 * row + 8 * col.
615+ ;; Store row in $81.
616+ sta $81
617+ ;; Set upper 2 bits of $80 to lower 2 bits of row
618+ ;; (other bits of $80 are irrelevant at this point).
619+ lsr
620+ ror
621+ ror
622+ sta $80
623+ ;; Add $81 to (row >> 2) to get row + (row >> 2).
624+ rol
625+ and #$3f
626+ clc
627+ adc $81
628+ sta $81
629+ ;; Mask out lower 6 bits of $80, then shift right.
630+ ;; This makes $80 at most #$60.
631+ lda $80
632+ and #$c0
633+ lsr
634+ sta $80
635+ ;; Add col << 2.
636+ txa
637+ asl
638+ asl
639+ ;; At this point, a is at most #$9c.
640+ ;; Add $80. This makes it at most #$fc, so no carry.
641+ adc $80
642+ ;; Shift left one more time. This can carry.
643+ asl
644+ sta $80
645+ ;; Add display base.
646+ lda #$20
647+ adc $81
648+ sta $81
649+ rts
650+
651+show:
652+;;; Displays a number of characters.
653+;;; In:
654+;;; SHOWADDR address of first character to show (2 bytes).
655+;;; SHOWCTR number of characters to show.
656+showl:
657+ ldy #0
658+ lda (SHOWADDR), y
659+ jsr showchr
660+ inc SHOWADDR
661+ bne showok
662+ inc SHOWADDR + 1
663+showok:
664+ dec SHOWCTR
665+ bne showl
666+showend:
667+ rts
668+
669+showchr:
670+;;; Displays a character at the current cursor position
671+;;; and updates the cursor position.
672+;;; In:
673+;;; a Character to display.
674+ sta SAVEA
675+ lda $a3
676+ pha
677+ lda $a2
678+ pha
679+ lda $a1
680+ pha
681+ lda $a0
682+ pha
683+ tya
684+ pha
685+ lda SAVEA
686+ pha
687+ jsr adjcur
688+ pla
689+ asl
690+ rol
691+ rol
692+ tay
693+ rol
694+ and #7
695+ clc
696+ adc #>FONTBASE
697+ sta $a3
698+ tya
699+ and #$f8
700+ sta $a2
701+ lda CURPOS
702+ sta $a0
703+ adc #8
704+ sta CURPOS
705+ lda CURPOS + 1
706+ sta $a1
707+ adc #0
708+ sta CURPOS + 1
709+ jsr copy8
710+ pla
711+ tay
712+ pla
713+ sta $a0
714+ pla
715+ sta $a1
716+ pla
717+ sta $a2
718+ pla
719+ sta $a3
720+ rts
721+
722+showhex:
723+;;; Print a as hex.
724+ sta SAVEA
725+ tya
726+ pha
727+ lda SAVEA
728+ pha
729+ lsr
730+ lsr
731+ lsr
732+ lsr
733+ tay
734+ lda hexits, y
735+ jsr showchr
736+ pla
737+ and #$0f
738+ tay
739+ lda hexits, y
740+ jsr showchr
741+ pla
742+ tay
743+ rts
744+
745+showint:
746+;;; In:
747+;;; $a0..$a1 number to show.
748+ lda BUFPTR
749+ pha
750+ sta SHOWADDR
751+ lda BUFPTR + 1
752+ sta SHOWADDR + 1
753+ jsr putint
754+ jmp showintd
755+
756+showuint:
757+;;; In:
758+;;; $a0..$a1 number to show.
759+ lda BUFPTR
760+ pha
761+ sta SHOWADDR
762+ lda BUFPTR + 1
763+ sta SHOWADDR + 1
764+ jsr putuint
765+ lda BUFPTR
766+ sec
767+ sbc SHOWADDR
768+ sta SHOWCTR
769+ jsr show
770+showintd:
771+ pla
772+ sta BUFPTR
773+ rts
774+
775+showspc:
776+ lda #$20
777+ jmp showchr
778+
779+twiack:
283780 ;;; Clobbers a.
284781 lda #$1f
285-twi_send_bit:
782+twibit:
286783 sta SERCR
287784 ora #$40
288785 sta SERCR
289786 and #$bf
290787 sta SERCR
291788 rts
292-
293-twi_nak:
789+
790+twinak:
294791 ;;; Clobbers a.
295792 lda #$9f
296- jmp twi_send_bit
297-
298-twi_recv_byte:
793+ jmp twibit
794+
795+twigetb:
299796 ;;; Receives a byte over TWI. This function does not send an ACK or NAK,
300-;;; so twi_ack or twi_nak must be called to complete the receipt of the
797+;;; so twiack or twinak must be called to complete the receipt of the
301798 ;;; byte.
302799 ;;; Out:
303800 ;;; a The byte received.
@@ -305,17 +802,17 @@
305802 lda #$9f
306803 sta SERCR
307804 ldx #8
308-twi_recv_byte_loop:
805+twigetbl:
309806 lda #$df
310807 sta SERCR
311808 and #$bf
312809 sta SERCR
313810 dex
314- bne twi_recv_byte_loop
811+ bne twigetbl
315812 lda SERIR
316813 rts
317814
318-twi_restart:
815+twiresta:
319816 ;;; Sends a TWI restart.
320817 ;;; Out:
321818 ;;; a 0 if successful. Any other value indicates an error.
@@ -329,9 +826,9 @@
329826 nop
330827 nop
331828 nop
332- jmp twi_start
829+ jmp twistart
333830
334-twi_send_byte:
831+twisendb:
335832 ;;; Preconditions:
336833 ;;; TWI start must have been sent.
337834 ;;; In:
@@ -342,7 +839,7 @@
342839 ;;; Clobbers x, $60.
343840 sta $60
344841 ldx #8
345-twi_send_byte_loop:
842+twisbl:
346843 lda $60
347844 and #$80
348845 ora #$1f
@@ -353,7 +850,7 @@
353850 and #$bf
354851 sta SERCR
355852 dex
356- bne twi_send_byte_loop
853+ bne twisbl
357854 ora #$80
358855 sta SERCR
359856 ora #$40
@@ -366,7 +863,7 @@
366863 and #1
367864 rts
368865
369-twi_start:
866+twistart:
370867 ;;; Out:
371868 ;;; a 0 if successful. Any other value means an error occurred.
372869 lda #$5f
@@ -374,8 +871,8 @@
374871 ;; Drive down the clock signal 8us (15 clock cycles) later.
375872 ;; It takes 6 cycles to execute the and and sta, so we need
376873 ;; to delay for 9 cycles - one jmp and 3 nops.
377- jmp twi_start_delay
378-twi_start_delay:
874+ jmp twistadl
875+twistadl:
379876 nop
380877 nop
381878 nop
@@ -384,7 +881,7 @@
384881 lda #0
385882 rts
386883
387-twi_stop:
884+twistop:
388885 ;;; Clobbers a.
389886 lda #$1f
390887 sta SERCR
@@ -405,10 +902,25 @@
405902 _end:
406903 jmp _end
407904
905+bytess: .byt "bytes"
906+
907+hexits: .byt "0123456789abcdef"
908+
909+kbmap: .byt $1b,"123456",$00
910+ .byt "`",$09,"qerty",$00
911+ .byt $00,"awsdfg",$00
912+ .byt ",zxcvbn "
913+ .byt "=",$08,"-0987",$00
914+ .byt "]",$5c,"[pouh",$00
915+ .byt "'",$0d,"lkijm",$00
916+ .byt "./;",$1e,$1c,$1d,$1f,$00
917+
918+uinttbl: .word 80, 800, 8000, 40000
919+
408920 .dsb $fffa-*,$ff
409-nmivec:
921+nmivec:
410922 .word NMIHNDLR
411-rstvec:
923+rstvec:
412924 .word _start
413-irqvec:
925+irqvec:
414926 .word IRQHNDLR
Show on old repository browser