Diagnostic Program
From
This program tests the basic capabilities of the SUPERPROTO board. Connect an LED to 6522A port A, pin 0 and run this program to test the SUPERPROTO and many of it's basic capabilities. The program also demonstrates some the fundamentals of Apple I/O including:
- I/O Select and I/O Strobe memory region usage
- Usage of Video Ram void memory location for I/O variables
- 6522A timer functionality
- 6522A Interrupt functionality
- Basic 6522A output port functionality
- Autostart Capability
- Proper way to write to the EEPROM
This program can be loaded into your SUPERPROTO by using this simple iPod to cassette port technique
- Insert SUPERPROTO card into slot 7, making sure write enable jumper is in place
- Load this file [1] into your ipod.
- Connect the iPod to the cassette input jack of your Apple ][
- Set up your iPod to play this file at maximum volume
- Go to the Apple monitor prompt (from Basic type call -151)
- Read into apple memory with the following command: 800.9F3R
- Start playing this AIF file
- Setup memory copy by typing 1A: 00 08 F3 09 00 C7
- Copy to SUPERPROTO by typing 900G
- Run the program by typing 7 cntrl-P
- The pass and interrupt count should be printed about every 2 minutes and should increment together with each pass completed
This diagnostic program was hacked together as a quick way to test basic features of the SUPERPROTO, but I wouldn't consider the code refined enough for production purposes.
PROCESSOR 6502
LIST ON
;-------------------------------------------------------------------------
; Defines - this code can be built one of four ways
; 1. to run in RAM
; 2. to run out of Hobbycard EEPROM
;
; select one of these three options
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
; Constants
;-------------------------------------------------------------------------
BS EQU $DF ;Backspace key, arrow left key
CR EQU $8D ;Carriage Return
ESC EQU $9B ;ESC key
PROMPT EQU "\" ;Prompt character
;-------------------------------------------------------------------------
; MONITOR FUNCTIONS
;-------------------------------------------------------------------------
COUT EQU $FDED ;Backspace key, arrow left key
IOSAVE EQU $FF4A ;Save all registers
IOREST EQU $FF3F ;Restore all registers
HOME EQU $FC58 ;Clear Screen
MOVE EQU $FE2C ;Move memory
MON EQU $FF65 ;Monitor entry point
SETKBD EQU $FE89 ;IN#0 sets default input vector
SETVID EQU $FE93 ;PR#0 sets default output vector
WAIT EQU $FCA8 ;wait function
PRBYTE EQU $FDDA ;print hex byte
NXTA4 EQU $FCB4 ;inc A4 and A1 until A1 = A2
;-------------------------------------------------------------------------
; I/O FUNCTIONS
;-------------------------------------------------------------------------
KEYBOARD EQU $C000 ;keyboard data
KEYSTROBE EQU $C010 ;clears keyboard data
;-------------------------------------------------------------------------
; 6522A FUNCTIONS
;-------------------------------------------------------------------------
TMR2L EQU $c088 ;timer2 low byte
; write: load LS byte
;
; read: to read low counter and clear interrupt
TMR2H EQU $c089 ;timer2 high byte
; wrt: high byte, transfer high and low to counter & enable int
; rd: read high counter
;
ACR EQU $c08B ;aux control register
;bit 5 = 0 timer 2 one shot mode
;bit5 = 1 timer 2 count pulses output on PB 6
;
IFR EQU $c08C ;interrupt flag register
; read: bit 7 state of IRQ, bit 5 timer 2 interrupt pending
; write: set bit to clear interrupt
;
IER EQU $c08E ;interrupt enable register
;bit 7 = 1 to set
;bit 7 = 0 to clear
;bit 5 = timer 2
;-------------------------------------------------------------------------
; Memory declaration
;-------------------------------------------------------------------------
WINDOWTOP EQU $22 ;top edge of window
HEX1L EQU $24 ;End address of dump block
HEX1H EQU $25
HEX2L EQU $26 ;Begin address of dump block
HEX2H EQU $27
SAVEINDEX EQU $28 ;Save index in input buffer
LASTSTATE EQU $29 ;Last input state
;unused by monitor or applesoft
; address setup for move command
AD1L EQU $1a
AD1H EQU $1b
AD2L EQU $1c
AD2H EQU $1d
AD4L EQU $1e
AD4H EQU $1f
;address holding locations for monitor move command
A1L EQU $3c
A1H EQU $3d
A2L EQU $3e
A2H EQU $3f
A4L EQU $42
A4H EQU $43
IN EQU $0200 ;Input buffer
WORKING EQU $0800 ;Working Memory
FLIP EQU $C020 ;Output flip-flop
TAPEIN EQU $C060 ;Tape input
KBD EQU $C000 ;keyboard input
KBDCR EQU $C010 ;keybaord strobe clear
;---------------------------------------------------------------------------
; build in ACI Driver
;---------------------------------------------------------------------------
;BLD4RAM EQU 0
IFCONST BLD4RAM
ORG $800 ; build for memory
ELSE
ORG $c700 ; plug in hobbyboard
ENDIF
START:
BIT $20 ; pretend this is Disk 2, so autostart will run it automatically
BIT $00
BIT $03
BIT $3C
;------------------------------------------------------------------------
; make sure no other card has 2K block selected
;--------------------------------------------------------------------------
LDA $CFFF ;
;------------------------------------------------------------------------
; now figure out our slot
;--------------------------------------------------------------------------
JSR IOSAVE ; save registers
SEI ; block interrupts
JSR $FF58 ; move current PC to stack
TSX
LDA $0100,X ; fetch high address
STA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAY
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
STA $478,y ;save in scratchpad register
LDA #0 ;initialize pass count
STA $4f8,y ;save in scratchpad register
STA $6f8,y ;save interrupt count
;
; save default interrupt routine
;
LDA $3FE ;
STA $578,y
LDA $3FF
STA $5f8,y
;
; set up hobby board interupt handler
;
LDA #<HOBBYINTERRUPT
STA $3FE
IFCONST BLD4RAM
LDA #>HOBBYINTERRUPT
ELSE
LDA $07F8
ENDIF
STA $3FF
;
; restore normal COUT and CIN
;
JSR SETKBD
JSR SETVID
JSR HOME ;clear screen
;
; print banner
;
LDA #>BANNER
STA A1H
LDA #<BANNER
STA A1L
JSR PRINTSTRING
LDA #1 ; prevents banner from being scrolled off top
STA WINDOWTOP
LDA #>TESTSTART
STA A1H
LDA #<TESTSTART
STA A1L
JSR PRINTSTRING
;
; initialize 6522A counter interrupt
;
LDA $07F8
AND #$07 ; mask off $CX to get slot #
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
; setup timer 2 as a oneshot
LDA #$0
STA ACR,X
;
LDA #$ff ; change to $FF
STA TMR2L,X
STA TMR2H,X
;
LDA #$A0 ; enable interupt for Timer 2
STA IER,X
STRTTEST:
JSR PIATEST
CLI ; enable interupts
NOP ; give interrupts a chance to come in
NOP
SEI ; disable interrupts again
LDA KEYBOARD ;check to see if keyboard input (stops test)
BMI TESTEXIT ;yes clear strobe, print finished and back to monitor
LDA $CFFF ;clear strobe
;
; finished pass, increment count and print banner
;
LDA #>PASSED
STA A1H
LDA #<PASSED
STA A1L
JSR PRINTSTRING
LDA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAY
LDA $6f8,Y ;fetch interrupt count from scratchpad register
PHA ;save interrupt count
LDA $4F8,Y ;fetch pass count
TAX
INX ;increment count
TXA
STA $4f8,Y ;save count
JSR PRBYTE ;print hex number
LDA #>INTERUPTS
STA A1H
LDA #<INTERUPTS
STA A1L
JSR PRINTSTRING
PLA ;fetch interrupt counter
JSR PRBYTE
LDA #$8d
JSR COUT ;newline
SEC
BCS STRTTEST
TESTEXIT:
LDA KEYSTROBE ;clear keyboard strobe
LDA #0 ; reset window top
STA WINDOWTOP
LDA #>ABORTED
STA A1H
LDA #<ABORTED
STA A1L
JSR PRINTSTRING
;
; restore default interrupt routine
;
LDA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAY
LDA $578,y
STA $3FE ;
LDA $5f8,y
STA $3FF
JMP MON
HOBBYINTERRUPT:
LDA $CFFF
JMP HOBBYINT
IFCONST BLD4RAM
ORG $0900 ; build for memory
ELSE
ORG $C800 ; plug in hobbyboard:w
ENDIF
;
; MOVE from A1 to A4 - until A1 = ending address in A2
;
MOV:
LDY #0 ; index = 0
LDA AD1L
STA A1L
LDA AD1H
STA A1H
LDA AD2L
STA A2L
LDA AD2H
STA A2H
LDA AD4L
STA A4L
LDA AD4H
STA A4H
MOV2:
LDA (A1L),Y ; MOVE A1[0x3C] TO A2[0x3E] TO
STA (A4L),Y ; A4[0x42]
MOVEWAIT:
CMP (A4L),Y ; for eeprom - wait till write takes
BNE MOVEWAIT ; MSB not correct until write is done
JSR NXTA4
BCC MOV2
RTS
BEGIN:
PIATEST:
LDA $07F8 ; fetch currently active card
AND #$07 ; mask off $CX to get slot #
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
LDA #$FF
TAY
STA $C083,X ; set port A for output
BLINKLED:
STA $C081,X ; set port A, all bits on
JSR WAIT ; wait 1/2*(26+27*255+5*255^2) =166018 useconds
LDA #$0
STA $C081,X ; turn all bits off
LDA #$ff
JSR WAIT
LDA KEYBOARD
BMI BRKTEST
LDA #$ff
DEY
BNE BLINKLED ; continue forever
BRKTEST
RTS
PRINTSTRING:
LDY #0
PS1:
LDA (A1L),Y
BEQ PSDONE
ORA #$80
JSR COUT
INY
BNE PS1
PSDONE:
RTS
HOBBYINT:
LDA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAX
INC $6F8,X ;increment interrupt count
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
; clear timer 2 interrupt and restart
LDA #$FF
STA TMR2H,X ; clear interrupt from timer register
LDA #20
STA IFR,X ; clear interrupt from interrupt flag register
RTI
BANNER: DC "SUPER PROTO COPYRIGHT 2010 MIKE WILLEGAL",$0d,0
TESTSTART: DC "STARTING AUTOMATIC TEST",$0d,0
PASSED: DC "PASS: ",0
ABORTED: DC "TEST STOPPED BY KEYBOARD INPUT",$0d,0
INTERUPTS: DC " INTERRUPTS: ",0
IFCONST EXTRACODE
;
; make sure magic number is in STROBE space
;;
; move copy of code to DRAM
;
LDA #<BEGIN
STA A1L
LDA #>BEGIN
STA A1H
LDA #<END
STA A2L
LDA #>END
STA A2H
LDA #<WORKING
STA A4L
LDA #>WORKING
STA A4H
LDY #0
JSR MOVE ;put copy of program in DRAM
LDA #$C8
STA A1H
LDA #$00
STA A1L
TAX
` LDA $55
CMP (A1L),X
; BEQ BEGIN
WRITEEEPROM:
PHA
LDA #0
TAX
PLA
CMP (A1L),X ; only write if data is different than current data
BEQ WRITEDONE
STA (A1L),X
WRITEWAIT:
CMP (A1L),X
BNE WRITEWAIT
WRITEDONE:
RTS
ENDIF