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"
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