Monday, September 11, 2017

Super Serial Switch Setting Status

     Ok, So I thought i'd bring this all together and try out just a few more tricks before moving onto something more comprehensive.  Having automatically identified the slot assignment and storing the value in zp SLOT $07 we can do some useful things with it by loading it into Y and using it as an offset when interfacing with the SSC as previously discussed.  As a demonstration, ive chosen not the command and control registers for this task, but the LS365 IC by which the physical DIP switches on the card are read into the registers as required.  That is to say, I do not want to know what the COMMAND and CONTROL values are.  I want to know what they WOULD BE, if read from those switches.   That said, not all of the individual switches are wired to the LS365; 3 of them are not connected, and in its stead, Clear to send has been added to one pin of the LS365 so its kinda weird.

The program starts off just like the previous one. Identifying which slot the SSC is found in...

Checking for SSC Card... Found in -->02

The next three values presented are Baud:, Mode:, and Data:.  I decided since this program was cut and dry that I might as well have some fun with this.  Ill forgo talking about how the labels for these three values appear in the program, it should be obvious through the course of code.   A quick note that there is some setcursor routines added to make the printout more manageable.

BAUD
The first order of business is BAUD and its settings reside in Switch 1, so we get the value of SWONE,Y (Y being the offset of SLOT) and store it to TESTBYTE, where we store switch values temporarily, because i'm about to do weird things to the value in the Accumulator throughout this program. I did something here to save a lot of code and cycles, so I shall explain.  BAUD takes up BITS 7 through 4 as saved in TESTBYTE and I don't care about anything else right now so we apply an AND mask of #$F0 to the Accumulator such that:

BITS    76543210  
VALUE   01101100
MASK    11110000
RESULT  01100000


Whatever the result is in the Accumulator, four ROR instructions are immediately issued to that result as shown below.

RESULT  01100000
ROR     00110000
ROR     00011000
ROR     00001100

ROR     00000110

     What is left is a 4 bit value that can be used in looking up the speed in the list of values in memory in the BAUDS/BAUDS2 label shown at the bottom portion of program memory.  Each speed is separated by a space character in the listing.  The code is reading that entire area of memory and looking for key value #$A0(space)as an index.  It will keep passing these spaces as many times as the value derived in the Accumulator, in this case, 6 times (0110) and then print the label until the next space character is reached, ending the print action.  If you look at BAUDS below and count 6 spaces and then start reading you will see that.


Checking for SSC Card... Found in -->02
                                       
   Baud: 300                           



MODE
The mode pulls TESTBYTE into the Accumulator, though it could really just re-pull from the switch, but that would mean re-initializing Y each time, so thats a consideration where every byte and cycle counts, so consider that.   Anyway.   Accumulator is loaded and another AND mask is conducted, this time #$03


BITS    76543210  
VALUE   01101100
MASK    00000011
RESULT  00000000


Now were only dealing with a 2 bit value with four possibilities. Using the same technique as bauds it is found on the bottom of memory, in the label of modes, four such possibilities separated by spaces to arrive at a printed value, such that:


Checking for SSC Card... Found in -->02
                                       
   Baud: 300                           
   Mode: Communication                 



DATA
The final value DATA is not one but 3 separate values tied together.  This requires information from switch 2, so SWTWO is now loaded into TESTBYTE and at the same time the Accumulator.

DATA - The STOP BIT

This is one boolean value, BIT 6 that determines if the STOP BIT is a 1 or a 2, so the value in the Accumulator will need a mask of #$40

BITS    76543210  
VALUE   01010000
MASK    01000000
RESULT  01000000


The value is boolean so there is no fancy code, a test if done after the mask,  if the Accumulator is holding #$40, print a 1, of not print a 2.   A quick print of #$AD after that just prints a dash '-' so that

   Data:  1-


DATA - The DATA BIT

For the Data bit, almost the exact same process, boolean value, pull TESTBYTE into Accumulator, but this time mask is #$10

BITS    76543210  
VALUE   01010001
MASK    00010000
RESULT  00010000


If the Accumulator is holding #$10, print an 8, if not print a 7, followed by #$AD for a dash so that
   Data:  1-8-



DATA - The PARITY

This again uses the same convention but has four possibilities for an output via testing and comparison.  The loading of TESTBYTE into the Accumulator follows a mask of #$0C

BITS    76543210  
VALUE   01010001
MASK    00001100
RESULT  00010000


A result of #$00 or #$08 will print an N, #$04 prints an O and #$0C will print an E, resulting in
   Data:  1-8-N


The final output of the program should appear as shown below.

Checking for SSC Card... Found in -->02
                                       
   Baud: 300                           
   Mode: Communication                 
   Data: 1-8-N                         
                                       



Link to DSK file with code and executable here



****************************************************
*         **** COMMODORE 64 BASIC V2 ****          *
*      64K RAM SYSTEM  38911 BASIC BYTES FREE      *
*     READY.                                       *
*     LOAD"SSCSETTINGS",8,1                        *
****************************************************
*  ---Pulls the settings from the DIP switches---  *
*  This program builds off of the auto detect code *
*  to read the information off of the two DIP      *
*  switches and decipher the values into human     *
*  readable form reporting back to the screen      *
*  Note that not all switches are tied logically   *
*  and are wired through an LS365. 3 to be exact.  *
*  SW2-6, interrupts, SW1-7 and SW2-7 for the DCD. *
*  Existing but not written in this program is the *
*  state of CTS which can be read from SWTWO       *
*  Written and compiled natively on Merlin 8       *
*  No Emulators used...... TASM style formatting   *
*  Free for all to use - Jordan Rubin 2017         *
*  http://technocoma.blogspot.com                  *
*  More at www.youtube.com/c/JordanRubin6502       *
****************************************************
          ORG $2000      ; HIRES area unused and safe
COUT       = $FDED       ; Like C64 $FFD2
CH         = $24         ; Cursor Horizontal
CV         = $25         ; Cursor Vertical
PRBYTE     = $FDDA       ; HEXPRINT
TESTBYTE   = $0A         ; test byte area
LSB        = $08         ; Bottom half of memory address
MSB        = $09         ; Top half of memory address
HOME       = $FC58       ; CLS and Cursor to top POS
SLOT       = $07         ; Testing and storage of slot
DATAREG    = $C088       ; Needs slot added when called
STATUSREG  = $C089       ; Needs slot added when called
COMMANDREG  = $C08A      ; Needs slot added when called
CONTROLREG  = $C08B      ; Needs slot added when called
SWONE      = $C081       ; Needs slot added when called
SWTWO      = $C082       ; Needs slot added when called

************** Start of program
START
          JSR  HOME      ; Clear screen, and top left start
          LDY #$00

************** Prints Message on top of screen
PRINTMESSAGE
          LDA MESSAGELABEL,Y
          JSR COUT
          INY
          CPY #$19
          BNE PRINTMESSAGE

************** Init routine start at slot one and MSB C1
INIT
          LDA #$01       ; Starting slot is 1
          STA SLOT       ; Store it
          LDA #$C1       ; Starting MSB is C1
          STA MSB        ; Store it
          LDX #$00       ; Init X

************** The main testing routine
ROUTINE
          LDA LSBVAL,X   ; LSB comes from data at at LSBVAL
          STA LSB        ; For each x - 05, 07, 0B, 0C
          LDY #$00       ; We dont want an offset for this action
          LDA (LSB),Y    ; Cs05 content load, indirect index
          STA TESTBYTE   ; Store return to temp memory area
          LDA SSCID,X    ; Load expected SSCID value for x to a
          CMP TESTBYTE   ; Compare recieved value to a
          BNE NEXTSLOT   ; Not equal? Not an SSC, try next slot
          INX            ; Equal? X++
          CPX #$03       ; All four bytes passed?
          BEQ FOUND      ; We have found the SSC!!!
          JSR ROUTINE    ; Not four yet, repeat routine....

************** Action to proceed to next slot to test
NEXTSLOT
          LDX SLOT       ; Load current slot into X
          INX            ; Increment it
          CPX #$07       ; Passed the last slot to test
          BEQ GIVEUP     ; Give up, no SSC found....
          STX SLOT       ; Store new current slot value
          LDX MSB        ; load current MSB into X
          INX            ; Increment it
          STX MSB        ; Store it
          LDX #$00       ; Init X
          JSR ROUTINE    ; Try Routine again

************** What to do when no SSC is found
GIVEUP
          LDX #$00       ; Init X
:PR
          LDA NOTFOUND,X ; Print not found Label
          JSR COUT
          INX
          CPX #$0D
          BNE :PR
          JMP $3D0       ; Back to Basic

************** When an SSC is found

FOUND
          LDX #$00       ; Init X
:PR
          LDA FOUNDLABEL,X ; Print found label
          JSR COUT
          INX
          CPX #$0D
          BNE :PR
          LDA SLOT
          JSR PRBYTE     ; Print slot num to screen
          LDA SLOT       ; Load SLOT into A
          ROL
          ROL
          ROL
          ROL            ; Multiply by 0x10
          STA SLOT       ; Store slot into A, official slot value!
          LDY SLOT
          LDA SWONE,Y
          STA TESTBYTE
          AND #%11110000
          ROR
          ROR
          ROR
          ROR
          STA LSB

DISPVALS
          LDX #$03       ; Horiz offset
          LDY #$03       ; Vert offset
          JSR SETCURSOR  ; set
          LDX #$00
:PR
          LDA BAUDLABEL,X
          JSR COUT
          INX
          CPX #$06
          BNE :PR

BAUDRATE
          LDX #$00
          LDY #$00
:INDEXLOOP
          CPX LSB
          BEQ :PRINTBAUD
:TEST
          LDA  BAUDS,Y
          INY
          CMP #$A0
          BNE :TEST
          INX
          JSR :INDEXLOOP
:PRINTBAUD
          TYA
          TAX
          INY
:PR
          LDA BAUDS,X
          JSR  COUT
          INX
          CMP #$A0
          BNE :PR
MODESTEP
          LDX #$04
          LDY #$03
          JSR SETCURSOR
          LDX #$00
:PR
          LDA MODELABEL,X
          INX
          JSR COUT
          CPX #$06
          BNE :PR
          LDA TESTBYTE
          AND #000011
          STA LSB
MODE
          LDX #$00
          LDY #$00
:INDEXLOOP
          CPX LSB
          BEQ :PRINTMODE
:TEST
          LDA MODES,Y
          INY
          CMP #$A0
          BNE :TEST
          INX
          JSR :INDEXLOOP
:PRINTMODE
          TYA
          TAX
          INY
:PR
          LDA MODES,X
          JSR COUT
          INX
          CMP #$A0
          BNE :PR
NEXTSWITCH
          LDY SLOT
          LDA SWTWO,Y
          STA TESTBYTE
          AND #%01000000
          STA LSB
          LDX #$05
          LDY #$03
          JSR SETCURSOR
          LDX #$00
:PR
          LDA DATALABEL,X
          JSR COUT
          INX
          CPX #06
          BNE :PR
          LDA LSB
          CMP #$40
          BEQ :PRONE
          JSR :PRTWO
:PRONE
          LDA #$B1
          JSR :PROUT
:PRTWO
          LDA #$B2
          JSR :PROUT
:PROUT
          JSR COUT
          LDA #$AD
          JSR COUT
DBITS
          LDA TESTBYTE
          AND #010000
          CMP #$10
          BEQ :PREIGHT
          JSR :PRSEVEN
:PREIGHT
          LDA #$B8
          JSR :PROUT
:PRSEVEN
          LDA #$B7
          LSR :PROUT
:PROUT
          JSR COUT
          LDA #$AD
          JSR COUT
FORMAT
          LDA TESTBYTE
          AND #001100
          CMP #$00
          BEQ :N
          CMP #$08
          BEQ :N
          CMP #$04
          BEQ :O
          CMP #$0C
          BEQ :E
:N
          LDA #$CE
          JSR COUT
          JSR ENDLOOP
:O
          LDA #$CF
          JSR COUT
          JSR ENDLOOP
:E
          LDA #$C5
          JSR COUT
          JSR ENDLOOP

SETCURSOR
           STX  CV
          JSR $FD8E
          STY CH
          RTS

ENDLOOP
          JSR ENDLOOP

MESSAGELABEL ASC "Checking for SSC Card... "
FOUNDLABEL ASC "Found in --> "
NOTFOUND  ASC "Was not found"
SSCID      HEX 38,18,01,31 ; 4 identifying bytes for SSC
LSBVAL     HEX 05,07,0B,0C ; LSB for identifying memory areas
BAUDLABEL  ASC "Baud: "
MODELABEL  ASC "Mode: "
DATALABEL  ASC "Data: "
BAUDS      ASC "External 50 75 110 135 150 300 600 1200 "
BAUDS2     ASC "1800 2400 3600 4800 7200 9600 19,200"
MODES      ASC "COMMUNICATION SICP8EM PRINTER SICP8AEM"

No comments:

Post a Comment