2016-12-15 01:16:55 +00:00
;;; Apple II Language Card audit routines
;;; Copyright © 2016 Zellyn Hunter <zellyn@gmail.com>
! zone langcard {
2016-12-18 01:49:28 +00:00
2016-12-15 01:16:55 +00:00
lda MEMORY
cmp # 49
bcs +
+ print
! text "48K:SKIPPING LANGUAGE CARD TEST" , $ 8 D
+ printed
beq .done2
;; Setup - store differing values in bank first and second banked areas.
2016-12-18 01:49:28 +00:00
+ lda $ C08B ; Read and write bank 1
2016-12-15 01:16:55 +00:00
lda $ C08B
lda # $ 55
2016-12-18 01:49:28 +00:00
sta $ D17B ; $D17B is $53 in Apple II/plus/e/enhanced
2016-12-15 01:16:55 +00:00
cmp $ D17B
beq +
+ prerr $ 0003 ;; E0003: We tried to put the language card into read bank 1, write bank 1, but failed to write.
! text "CANNOT WRITE TO LC BANK 1 RAM"
+ prerred
beq .done2
+ sta $ FE1F ; FE1F is $60 in Apple II/plus/e/enhanced
cmp $ FE1F
beq +
+ prerr $ 0004 ;; E0004: We tried to put the language card into read RAM, write RAM, but failed to write.
! text "CANNOT WRITE TO LC RAM"
+ prerred
2016-12-15 03:57:37 +00:00
beq .done2
2016-12-18 01:49:28 +00:00
+ lda $ C083 ; Read and write bank 2
2016-12-15 01:16:55 +00:00
lda $ C083
lda # $ AA
sta $ D17B
cmp $ D17B
beq +
+ prerr $ 0005 ;; E0005: We tried to put the language card into read bank 2, write bank 2, but failed to write.
! text "CANNOT WRITE TO LC BANK 2 RAM"
+ prerred
2016-12-15 03:57:37 +00:00
beq .done2
;; Test that we're reading the right things
2016-12-18 01:49:28 +00:00
+ lda $ C088 ; RAM read, bank 1, write disabled
2016-12-15 01:16:55 +00:00
lda $ D17B
cmp # $ 55
2016-12-15 03:57:37 +00:00
beq ++
2016-12-15 01:16:55 +00:00
cmp # $ AA
bne +
+ prerr $ 0006 ;; E0006: Read $C088 (read bank 1), but the language card is still reading bank 2.
2016-12-15 03:57:37 +00:00
! text "$C088: BANK 2 ACTIVE"
2016-12-15 01:16:55 +00:00
+ prerred
2016-12-18 01:49:28 +00:00
beq .done2
2016-12-15 01:16:55 +00:00
+ cmp # $ 53
bne +
+ prerr $ 0007 ;; E0007: Read $C088 (read bank 1), but the language card is reading ROM.
! text "$C088: ROM ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done2
2016-12-17 03:35:28 +00:00
+ + prerra $ 0008 ;; E0008: Read $C088 (read bank 1), but the check byte ($D17B) is an unknown value.
2016-12-15 01:16:55 +00:00
! text "$C088: UNKNOWN BYTE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done2
+ + inc $ D17B
2016-12-15 03:57:37 +00:00
eor $ D17B
beq +
2016-12-17 03:35:28 +00:00
+ prerr $ 0009 ;; E0009: Read $C088 (read bank 1, write-protected), but successfully wrote byte ($D17B).
2016-12-15 03:57:37 +00:00
! text "$C088: ALLOWED WRITE"
+ prerred
2016-12-18 01:49:28 +00:00
.done2 beq .done3
2016-12-15 03:57:37 +00:00
2016-12-18 01:49:28 +00:00
+ lda $ C080 ; RAM read, bank 2, write disabled
2016-12-15 03:57:37 +00:00
lda $ D17B
cmp # $ AA
beq ++
cmp # $ 55
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 000 A ;; E000A: Read $C080 (read bank 2), but the language card is still reading bank 1.
2016-12-15 03:57:37 +00:00
! text "$C080: BANK 1 ACTIVE"
+ prerred
beq .done3
+ cmp # $ 53
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 000B ;; E000B: Read $C080 (read bank 2), but the language card is reading ROM.
2016-12-15 03:57:37 +00:00
! text "$C080: ROM ACTIVE"
+ prerred
beq .done3
2016-12-17 03:35:28 +00:00
+ + prerra $ 000 C ;; E000C: Read $C080 (read bank 2), but the check byte ($D17B) is an unknown value.
2016-12-15 03:57:37 +00:00
! text "$C080: UNKNOWN BYTE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done3
+ + inc $ D17B
2016-12-15 03:57:37 +00:00
eor $ D17B
beq +
2016-12-17 03:35:28 +00:00
+ prerr $ 000 D ;; E000D: Read $C080 (read bank 2, write-protected), but successfully wrote byte ($D17B).
2016-12-15 03:57:37 +00:00
! text "$C080: ALLOWED WRITE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done3
2016-12-15 03:57:37 +00:00
2016-12-18 01:49:28 +00:00
+ lda $ C081 ; ROM read, bank 2 no write
2016-12-15 03:57:37 +00:00
lda $ D17B
cmp # $ 53
beq ++
cmp # $ 55
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 000 E ;; E000E: Read $C081 (read ROM), but the language card is still reading bank 1.
2016-12-15 03:57:37 +00:00
! text "$C081: BANK 1 ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done3
2016-12-15 03:57:37 +00:00
+ cmp # $ AA
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 000 F ;; E000F: Read $C081 (read ROM), but the language card is reading bank 2.
2016-12-15 03:57:37 +00:00
! text "$C081: BANK 1 ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done3
2016-12-17 03:35:28 +00:00
+ + prerra $ 0010 ;; E0010: Read $C081 (read ROM), but the check byte ($D17B) is an unknown value.
2016-12-15 03:57:37 +00:00
! text "$C081: UNKNOWN BYTE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done3
2016-12-15 03:57:37 +00:00
+ + dec $ D17B
eor $ D17B
beq +
2016-12-17 03:35:28 +00:00
+ prerr $ 0011 ;; E0011: Read $C081 (read ROM), but successfully modified byte ($D17B).
2016-12-15 03:57:37 +00:00
! text "$C081: ALLOWED WRITE"
+ prerred
2016-12-18 01:49:28 +00:00
.done3 beq .done4
2016-12-15 03:57:37 +00:00
2016-12-18 01:49:28 +00:00
+ lda $ C089 ; ROM read, bank 1 write
2016-12-16 03:38:01 +00:00
lda $ D17B
cmp # $ 53
beq ++
cmp # $ 55
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 0012 ;; E0012: Read $C089 (read ROM), but the language card is still reading bank 1.
2016-12-16 03:38:01 +00:00
! text "$C089: BANK 1 ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
2016-12-16 03:38:01 +00:00
+ cmp # $ AA
bne +
2016-12-17 03:35:28 +00:00
+ prerr $ 0013 ;; E0013: Read $C089 (read ROM), but the language card is reading bank 2.
2016-12-16 03:38:01 +00:00
! text "$C089: BANK 1 ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
2016-12-17 03:35:28 +00:00
+ + prerra $ 0014 ;; E0014: Read $C089 (read ROM), but the check byte ($D17B) is an unknown value.
2016-12-16 03:38:01 +00:00
! text "$C089: UNKNOWN BYTE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
+ + inc $ D17B ; bank 1 now holds $54 instead of $55
2016-12-16 03:38:01 +00:00
eor $ D17B
beq +
2016-12-17 03:35:28 +00:00
+ prerr $ 0015 ;; E0015: Read $C089 (read ROM), but successfully modified byte ($D17B).
2016-12-16 03:38:01 +00:00
! text "$C089: ALLOWED WRITE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
2016-12-15 03:57:37 +00:00
2016-12-17 03:35:28 +00:00
+ lda $ C08B ; RAM read, bank 1
lda $ D17B
2016-12-18 01:49:28 +00:00
cmp # $ 54
2016-12-17 03:35:28 +00:00
beq ++
cmp # $ AA
bne +
+ prerr $ 0016 ;; E0016: Read $C08B (read bank 1), but the language card is still reading bank 2.
! text "$C08B: BANK 2 ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
2016-12-17 03:35:28 +00:00
+ cmp # $ 53
bne +
+ prerr $ 0017 ;; E0017: Read $C08B (read bank 1), but the language card is reading ROM.
! text "$C08B: ROM ACTIVE"
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
+ cmp # $ 55
2016-12-17 03:35:28 +00:00
bne +
2016-12-18 01:49:28 +00:00
+ prerr $ 0018 ;; E0018: Read $C08B (read bank 1); byte should have been previously incremented from ROM ($53) to $54 because of lda $C089 after previous lda $C081.
! text "$C08B: PREVIOUS WRITE FAILED"
2016-12-17 03:35:28 +00:00
+ prerred
2016-12-18 01:49:28 +00:00
beq .done4
2016-12-17 03:35:28 +00:00
+ + prerra $ 0019 ;; E0019: Read $C08B (read bank 1), but the check byte ($D17B) is an unknown value.
! text "$C08B: UNKNOWN BYTE"
+ prerred
2016-12-18 01:49:28 +00:00
.done4 beq .done5
2016-12-17 03:35:28 +00:00
+ +
2016-12-18 01:49:28 +00:00
+ lda $ C083 ; RAM read, bank 2
lda $ D17B
cmp # $ AA
beq ++
cmp # $ 54
bne +
+ prerr $ 001 A ;; E001A: Read $C083 (read bank 2), but the language card is still reading bank 1.
! text "$C083: BANK 1 ACTIVE"
+ prerred
beq .done5
+ cmp # $ 53
bne +
+ prerr $ 001B ;; E001B: Read $C083 (read bank 2), but the language card is reading ROM.
! text "$C083: ROM ACTIVE"
+ prerred
beq .done5
+ cmp # $ 52
bne +
+ prerr $ 001 C ;; E001C: Read $C083 (read bank 2); byte should have been previously NOT been writable to be decremented from ROM ($53) to $52 because of single lda $C081 after previous lda $C080.
! text "$C083: PREVIOUS WRITE SUCCEEDED"
+ prerred
beq .done5
+ + prerra $ 001 D ;; E001D: Read $C083 (read bank 2), but the check byte ($D17B) is an unknown value.
! text "$C083: UNKNOWN BYTE"
+ prerred
.done5 jmp .done
+ +
2016-12-18 03:06:15 +00:00
;; Parameterized tests
lda # < .tests
sta 0
lda # > .tests
sta 1
.outer
;; Initialize to known state:
;; - $55 in $D17B bank 1 (ROM: $53)
;; - $AA in $D17B bank 2 (ROM: $53)
;; - $55 in $FE1F (ROM: $60)
lda $ C08B ; Read and write bank 1
lda $ C08B
lda # $ 55
sta $ D17B
sta $ FE1F
lda $ C083 ; Read and write bank 2
lda $ C083
lda # $ AA
sta $ D17B
lda $ C080
ldy # 0
.inner
lda ( $ 0 ), y
cmp # $ ff
beq .test
tax
bmi +
2016-12-20 04:55:00 +00:00
ora # $ 80
sta .lda + 1
.lda lda $ C000
2016-12-18 03:06:15 +00:00
jmp ++
2016-12-20 04:55:00 +00:00
+ sta .sta + 1
.sta sta $ C000
2016-12-18 03:06:15 +00:00
+ + iny
bne .inner
.test ;; ... test the triple
inc $ D17B
inc $ FE1F
iny
;; y now points to d17b-current,fe1f-current,bank1,bank2,fe1f-ram test quintiple
;; Test current $D17B
lda ( 0 ), y
cmp $ D17B
beq +
lda $ D17B
pha
jsr .printseq
+ print
! text "$D17B TO CONTAIN $"
+ printed
lda ( 0 ), y
jsr PRBYTE
+ print
! text ", GOT $"
+ printed
pla
jsr PRBYTE
lda # $ 8 D
jsr COUT
2016-12-18 03:19:22 +00:00
jmp .datatesturl
2016-12-18 03:06:15 +00:00
+ iny
;; Test current $FE1F
lda ( 0 ), y
cmp $ FE1F
beq +
lda $ FE1F
pha
jsr .printseq
+ print
! text "$FE1F=$"
+ printed
lda ( 0 ), y
jsr PRBYTE
+ print
! text ", GOT $"
+ printed
pla
jsr PRBYTE
lda # $ 8 D
jsr COUT
2016-12-18 03:19:22 +00:00
jmp .datatesturl
2016-12-18 03:06:15 +00:00
+ iny
;; Test bank 1 $D17B
lda $ C088
lda ( 0 ), y
cmp $ D17B
beq +
lda $ D17B
pha
jsr .printseq
+ print
! text "$D17B IN RAM BANK 1 TO CONTAIN $"
+ printed
lda ( 0 ), y
jsr PRBYTE
+ print
! text ", GOT $"
+ printed
pla
jsr PRBYTE
lda # $ 8 D
jsr COUT
2016-12-18 03:19:22 +00:00
jmp .datatesturl
2016-12-18 03:06:15 +00:00
+ iny
;; Test bank 2 $D17B
lda $ C080
lda ( 0 ), y
cmp $ D17B
beq +
lda $ D17B
pha
jsr .printseq
+ print
! text "$D17B IN RAM BANK 2 TO CONTAIN $"
+ printed
lda ( 0 ), y
jsr PRBYTE
+ print
! text ", GOT $"
+ printed
pla
jsr PRBYTE
lda # $ 8 D
jsr COUT
2016-12-18 03:19:22 +00:00
jmp .datatesturl
2016-12-18 03:06:15 +00:00
+ iny
;; Test RAM $FE1F
lda $ C080
lda ( 0 ), y
cmp $ FE1F
beq +
lda $ FE1F
pha
jsr .printseq
+ print
! text "RAM $FE1F=$"
+ printed
lda ( 0 ), y
jsr PRBYTE
+ print
! text ", GOT $"
+ printed
pla
jsr PRBYTE
lda # $ 8 D
jsr COUT
2016-12-18 03:19:22 +00:00
jmp .datatesturl
2016-12-18 03:06:15 +00:00
+ iny
lda ( $ 0 ), y ; Done with the parameterized tests?
cmp # $ ff
beq .over
clc
tya
adc $ 0
sta $ 0
bcc +
inc $ 1
+ jmp .outer
2016-12-18 03:19:22 +00:00
.datatesturl
2016-12-20 04:55:00 +00:00
+ prerr $ 001 E ;; E001E: We initialized $D17B in RAM bank 1 to $55, $D17B in RAM bank 2 to $AA, and $FE1F in RAM to $55. Then, we perform a testdata-driven sequence of LDA and STA to the $C08X range. Finally we (try to) increment $D17B and $FE1F. Then we test (a) the current live value in $D17B, (b) the current live value in $FE1F, (c) the RAM bank 1 value of $D17B, (d) the RAM bank 2 value of $D17B, and (e) the RAM value of $FE1F, to see whether they match expected values. $D17B is usually $53 in ROM, and $FE1F is usally $60. For more information on the operation of the language card soft-switches, see Understanding the Apple IIe, by James Fielding Sather, Pg 5-24.
2016-12-18 03:19:22 +00:00
! text "DATA-DRIVEN TEST FAILED"
+ prerred
beq .done
2016-12-18 03:06:15 +00:00
.printseq
tya
pha
+ print
! text "AFTER SEQUENCE OF:" , $ 8 D , "LDA $C080" , $ 8 D
+ printed
ldy # $ 0
- lda ( $ 0 ), y
cmp # $ ff
beq +++
tax
bmi +
lda # 'L'
jsr COUT
lda # 'D'
bne ++
+ lda # 'S'
jsr COUT
lda # 'T'
+ + jsr COUT
+ print
! text "A $C0"
+ printed
txa
ora # $ 80
jsr PRBYTE
lda # $ 8 D
jsr COUT
iny
bne -
+ + +
+ print
! text "INC $D17B" , $ 8 D , "INC $FE1F" , $ 8 D , "EXPECTED "
+ printed
pla
tay
rts
2016-12-18 03:19:22 +00:00
.tests
;; Format:
;; - $ff-terminated list of C0XX addresses (0-F to read C08X, 80-8F to write C0XX).
;; - quint: expected current $d17b and fe1f, then d17b in bank1, d17b in bank 2, and fe1f
2016-12-20 04:55:00 +00:00
;; (All sequences start with lda $C080, just to reset things to a known state.)
! byte $ 8 , $ ff ; Read $C088 (RAM read, write protected)
! byte $ 55 , $ 55 , $ 55 , $ AA , $ 55 ;
! byte $ 1 , $ 1 , $ ff ; Read $C081, $C081 (read ROM, write RAM bank 2)
! byte $ 53 , $ 60 , $ 55 , $ 54 , $ 61 ;
! byte $ b , $ b , $ ff ; Read $C08B, $C08B (read/write RAM bank 1)
! byte $ 56 , $ 56 , $ 56 , $ AA , $ 56 ;
! byte $ b , $ 8 b , $ b , $ ff ; Read $C08B, write $C08B, read $C08B (read RAM bank 1, no write)
! byte $ 55 , $ 55 , $ 55 , $ AA , $ 55 ;
2016-12-18 03:19:22 +00:00
! byte $ ff
nop ; Provide clean break after data when viewing disassembly
nop
nop
2016-12-18 03:06:15 +00:00
.over
2016-12-18 01:49:28 +00:00
2016-12-15 01:16:55 +00:00
;; Success
+ print
! text "LANGUAGE CARD TESTS SUCCEEDED" , $ 8 D
+ printed
.done
} ;langcard