# # SERIAL PORT "DAS BLINKEN LIGHTS" # # IN ADDITION TO BLINKING FRONT PANEL LEDS, THIS PROGRAM WILL # # RANDOMLY LIGHT AND EXTINGUISH A MATRIX OF 39x22 LEDS ON A # # VT-100 COMPATIBLE TERMINAL CONNECTED TO THE SERIAL PORT. # # Assemble with Tom Crosley's kenbak_asm assembler # # Type any character to restore terminal and stop; START restarts. # # Version 1.0 06/11/2019 Original version (used "o" for LEDs) # # Version 2.0 06/13/2019 Use VT-100 Diamonds for LEDs # # Version 2.1 06/14/2019 Offset alternate rows # # Version 2.2 05/22/2021 Replace SHRB (April 2021 & earlier F/W bug) # #----------------------- # # ASCII CHARACTER CODES # #----------------------- ESC EQU 033 # ESC character NUL EQU 000 # String terminator ZERO EQU 060 # "0" OFF EQU 040 # " " ON EQU 0140 # "`" (Diamond) ORG 0 # #-------------------- # # REGISTERS UP FRONT # #-------------------- A DB 000 B DB 000 X DB 000 P DB MAIN # #------------------------------ # # ANSI ESCAPE SEQUENCE STRINGS # #------------------------------ CLSHCUR DB ESC DS "[2J" DB ESC DS "[?25l" DB ESC DS "(0" DB NUL # Clear screen, hide cursor, graphics on CLSSCUR DB ESC DS "[H" DB ESC DS "[J" DB ESC DS "[?25h" DB ESC DS "(B" DB NUL # Clear screen, home/show cursor, gfx off LIGHT DB ESC DS "[rr;ccHo" DB NUL # ON or OFF in o at row rr column cc # #----------- # # FUNCTIONS # #----------- # #----------------------------------------------------- # # DIVIDE B BY X, QUOTIENT->A, REMAINDER->B # # BOTH B AND X MUST BE POSITIVE, RESULTS ARE POSITIVE # #----------------------------------------------------- DIVIDE NOP # Space for return address LDA #0 # Initialize quotient REPSUB SUBB X # Repeated subtraction JBLT DIVEND # Division ended ADDA #1 # Increment quotient JMP REPSUB # More subtractions needed DIVEND ADDB X # Restore remainder JMP (DIVIDE) # Return # #-------------------------------------------- # # RETURN RANDOM NUMBER BETWEEN 1 AND X IN B. # # IF X NOT POWER OF 2, DISTRIBUTION WILL BE # # BIASED SOMEWHAT TOWARD THE LOW END DUE TO # # LIMITED RESOLUTION (7-BIT POSITIVE VALUES) # #-------------------------------------------- RAND NOP # Space for return address LDA #021 # SYSX operation: get random byte SYS # Get random byte STB OUT # Just for fun SYS # Get random byte LDA #0220 # SYSX operation: set control leds SYS # Just for fun # #SHRB 1 # Make random number positive (was a F/W bug) SET0 B,7 # Make random number positive (works w/all F/W) CALL DIVIDE # Divide by X ADDB #1 # Increase remainder by 1 JMP (RAND) # Return # #----------------------------------------------------- # # LIGHT (A=ON) OR EXTINGUISH (A=OFF) ONE RANDOM LIGHT # #----------------------------------------------------- ONELIGHT NOP # Space for return address STA LIGHT+8 # Store OFF or ON in LIGHT o LDX #22 # 22 rows of lights CALL RAND # Random row 1-22 in B ADDB #1 # Random row 2-23 in B STB ROW # Save row for later LDX #10 # Divisor CALL DIVIDE # Divide row by 10 ADDA #ZERO # Convert 10s place to ASCII ADDB #ZERO # Convert 1s place to ASCII STA LIGHT+2 # Store 10s place in LIGHT row STB LIGHT+3 # Store 1s place in LIGHT row LDX #39 # 39 columns of lights CALL RAND # Random column 1-39 in B SHLB 1 # Random even column 2-78 in B SKP0 ROW,0 # Skip if row is even ADDB #1 # Odd rows use odd columns LDX #10 # Divisor CALL DIVIDE # Divide column by 10 ADDA #ZERO # Convert 10s place to ASCII ADDB #ZERO # Convert 1s place to ASCII STA LIGHT+5 # Store 10s place in LIGHT column STB LIGHT+6 # Store 1s place in LIGHT column LDX #LIGHT # String to be written CALL WSTRING # Light or extinguish at row,column JMP (ONELIGHT) # Return ORG 0204 # Skip past central registers # #--------------------------------------------------------- # # WRITE NUL-TERMINATED STRING AT ADDRESS X TO SERIAL PORT # #--------------------------------------------------------- WSTRING NOP # Space for return address WMORE LDB (X) # Get next char of string JBEQ (WSTRING) # No more string when NUL, so return LDA #0223 # SYSX operation: write serial port SYS # Write character to serial port ADDX #1 # Increment X to next char JMP WMORE # Write more characters ROW EQU WSTRING # Share transient byte # #-------------- # # MAIN PROGRAM # #-------------- MAIN LDX #CLSHCUR # String to be written CALL WSTRING # Clear screen, hide cursor, gfx on LDA #0221 # SYSX operation: Seed random number gen LDB #0 # Use random seed SYS # Seed random number generator randomly MAINLOOP LDA #ON # ON CALL ONELIGHT # Light one random light LDA #OFF # OFF CALL ONELIGHT # Extinguish one random light LDA #OFF # OFF CALL ONELIGHT # Extinguish another random light LDA #023 # SYSX operation: read serial port SYS # Read character from serial port JBEQ MAINLOOP # Ad nauseum until character typed LDX #CLSSCUR # String to be written CALL WSTRING # Clear screen, show cursor, gfx off HLT # Halt computer JMP MAIN # Restart if START pressed