Page last updated Aug 13 2022, added display ROM July 25 2024.This Web page provides Jack Noble's interrupt handler and examples for the 1802 Membership Card Rev L front-panel. See the linked Web page for the Rev L support page here at retrotechnology.com. That page includes the manual and descriptions and schematics for the display hardware and the 1802 Membership Card CPU. - Herb Johnson
For documentation on the 1802 interrupts, you’ll have to go directly to the RCA 1802 manuals. Few 1802 programs use the interrupt and they often don’t explain how they work. The original document is in RCA's COSMAC User's Manual MPM-201B, as I’ve exerpted on this linked page. That document refers to “RCABUG”, an old 1802 monitor, described on this linked Web page. - Herb Johnson
In mid-July 2022, Jack Noble built the Rev L 1802 Membership card, and produced an interrupt handler and examples for use with the 6-digit 7-segment display. These notes and the code of the examples, were published by Jack on the cosmacelf groups.io email list; in the thread "New Rev. L 1802MC front panel built"). Jack was assisted by Lee Hart and Chuck Yakym. Lee Hart distributes this same code (less commentary) in this file, and also on his 1802 Membership Card Web page as part of his other ROM images.
The Rev L digit display is scanned by a hardware clock which enables each digit and also produces a pulse for each digit-time, and a pulse for the first (last?) digit. The digit-time pulse is an interrupt, and the first/last digit pulses the EF2 line. A ROM decodes the outputs of OUT 4, into bits that drive each LED segment (and decimal point). As the hardware clock enables each LED digit, whatever software puts out on OUT 4 is decoded by the ROM, and drives that digit's segments. Without software, the display can be set to show OUT 4 content as two hex digits.
In practice, the resistor/capacitor timing on the hardware clock needed adjustment, as did the width of the interrupt pulse. Lee Hart in private correspondence described those changes, as below. Following his description, I show Jac Noble's code examples. Jack's code did not have comments. I incorporated his posted comments plus my code interpretations, as coding comments. Please contact me if any code or comments are in error. - Regards, Herb Johnson
July 2024: display ROM Here's an Intel Hex file of the 27C32 display ROM for the Rev L/L1 six-digit display. This file is from a March 2022 version of the ROM. I hope to confirm with Lee Hart it's the 2024 version as well. - Herb
You may have noticed the animated GIF on my 1802 Membership Card Web page. It's running Jack Noble's scrolling message program. :-) To make it work, I changed R17 from 3.3k to 1.5k, and changed Q4 and Q6 from FJN335 back to FJN3303.
The original values worked to provide a ~80 usec /INT low pulse. Jack's and Chuck Yakym's interrupt handlers were faster than that, so they had to "pad out" the interrupt handler so /INT had gone back high by the time the interrupt handler returned.
I reduced R17 to shorten the /INT low time to 40 usec. But the 4071 OR gate U9B didn't have enough drive for the 1.5k + 4.7k + 4.7k base resistors in the two transistors. The OR gate output wasn't going high enough to cleanly disable the EPROM /CE pin, so there was "ghosting" in the LEDs as it stepped to the next digit.
So, I went back to the FJN3303 (used on earlier revs) because it has 22k base resistors. That reduced the load on the OR gate, so everything works nicely again. :-)
In the programs below, the INCL "1802reg.asm" establishes R0 as 0, R1 as 1, etc to designate the registers. Syntax for the A18 1802 cross assembler is assumed but it's a common 1802 syntax. For original A18 or other original 1802 assemblers, the LOAD pseudo-op is not supported. You’ll have to replace the "LOAD” pseudoop with conventional 1802 MOV instructions as below. - Herb
VALUE: DW 1234 ;change this value of course LOAD Rx, VALUE ;choose register R0 to RF F8 12 LDI high VALUE Bx PHI Rx F8 34 LDI low VALUE Ax PLO Rx
; Interrupt Service Routine by Jack Noble July 19 2022 ; for 1802 Membership Card Rev L six-digit display ; commentary by Jack Noble, some edits by Herb Johnson ; ; To set up the ISR, in your program source define INTBUF and INTPTR ; to be one each of registers R3-RF (doesn't matter). ; Then disable interrupts, set R1 to point to the ISR (label "INT"). ; Set R2 to point to some stack space. ; Then set register INTBUF to point to 6 bytes of a default message in memory. ; The value in INTPTR does not need to be initialized. ; Then re-enable interrupts, and you're good to go! ; ; R1, R2 and INTPTR must be preserved by all running programs. ; On interrupt, R1 is automatically the PC, and X is set to R2 automatically. ; ; In use: INTBUF is set to point to wherever in memory ; contains the 6-byte message to be displayed. ; ; INTPTR is used by the ISR to keep track of where it is in the message during display ; (So don't touch that register). ; ; issues: ; ; For the first refresh cycle after starting the ISR, the display will show garbage. ; This is because INTPTR has not yet been set to point to the message pointed to by INTBUF. ; But it's not really an issue as it just causes a small flicker on power-up. ; If this is unacceptable, set INTPTR to the same address as INTBUF ; and test/wait until EF2 goes high (logic zero) before enabling the interrupt. INCL "1802reg.asm" ;ORG ????? ;of course, handler must be in memory somewhere! INTRET: RET ;usual 1802 return route, sets current PC=R1 to next instruction ;meanwhile old X and P are restored as saved below ; and you return to your running program INT: SEX R2 ;.... which is the interrupt entry point DEC R2 SAV ;save T state (old X and P) for RET to restore DEC R2 STXD LDN INTPTR STR R2 ;set up RX=R2 to point to char to display OUT 4 ;and OUT sends char to display latch NOP ;hang loose for some CPU clock time you have to determine... NOP ; past the length of the interrupt signal NOP ; to avoid double interrupts NOP NOP NOP INC INTPTR ;point to next char to display B2 NODSP6 ;monitor EF2 for display reset timer (first char timer) ;if not ready don't reset display pointer GHI INTBUF ;if ready then reset INTPTR to start of message PHI INTPTR GLO INTBUF PLO INTPTR NODSP6: LDXA ;(not sure what this does....) BR INTRET ; setting up the return from interrupt ;END ;no end needed if embedded in user codes
; simple program to establish and initialize interupt handler ; and display an initial message - and loop otherwise. ; code and commentary by Jack Noble, some edits by Herb Johnson ; For this program to run, the interrupt handler MUST be in memory. INCL "1802reg.asm" INTBUF EQU RF ;points to 6 byte message INTPTR EQU RE ;used by INT to scan message ORG $0000 ;on reset 1802 goes to 0000H SEX R0 ;may not be necessary on reset entry DIS ;but must disable interrupts until established DB $00 ;also necessary after DIS LOAD R1, INT ;must set R1 ONCE for handler entry address ;"INT" is the address of the interrupt handler! LOAD R2, $017F ;R2 is stack space set ONCE, this is application-specific ;your stack address will be different! LOAD RF, MESG ;INTBUF set to initial/default message ;INTPTR is in use by handler to scan message RET ;force interrupt enable DB $20 ;this is necessary after RET ;running user programs *cannot modify* R1, R2, INTBUF, INTPTR LOCK: BR LOCK ;just a place to run between interrupts MESG: DB "HELLO!" ;initial six-byte ASCII message END
; program to initialize interrupt handler ; and display a message in "banner" or scrolling mode ; code and commentary by Jack Noble, some edits by Herb Johnson INCL "1802reg.asm" INTBUF EQU RF ;points to 6 byte message INTPTR EQU RE ;used by INT to scan message ORG $0000 SEX R0 ;may not be necessary on reset entry DIS ;must disable interrupts until established DB $00 ;this is also necessary LOAD R1, INT ;must set R1 ONCE for handler entry LOAD R2, $3FFF ;R2 is stack space set ONCE this is use-specific LOAD RF, BANNER ;INTBUF set to start of banner message ;INTPTR is in use by handler to scan message RET ;force interrupt enable DB $20 ;this is also necessary ;registers R1, R2, INTBUF and INTPTR *must* be preserved in user's programs LOAD R4, BANNERLEN ;length of banner message, less six bytes ;remember, 6-character display LOOP: LDI $40 ;some delay time, using R3 PHI R3 ;put in high byte, clock low byte DELAY: ;give time for human to read display before scroll DEC R3 ;decr low byte 256 times to dec high byte GHI R3 BNZ DELAY ;delay depends on CPU speed INC RF ;advance INTBUF to scroll to left ;int handler displays 6 chars following DEC R4 GLO R4 BNZ LOOP ;countdown with R4 LOAD RF, BANNER LOAD R4, BANNERLEN BR LOOP ;note, for the above program, it doesn't know about the start or ;the end of the message, so it must be padded with 6 spaces each end BANNER: DB " 1802 MEMbErshIp CArd " BANNEREND: BANNERLEN EQU BANNEREND - BANNER - 6 END
This page and edited content is copyright Herb Johnson (c) 2024, except for content provided by Lee Hart or Jack Noble. Contact Herb at www.retrotechnology.com, an email address is available on that page..