       OPT  XREF,CYCLE,WRAP
       NAM  Softy Firmware
       SPC
SYSTEM NOP             the SC/MP designers are morons
       SPC
       LDI  $06
       XPAH P2
       LDI  $70
       XPAL P2         P2 := $0670
       SPC
LOOP1  ST   1(P2)+     clear location pointed to by
       XPAL P2         P2 and increment P2 until LSB
       JZ   EXIT1      is zero. This clears all Screen
       XPAL P2         scatch pad locations and i/o
       JMP  LOOP1      registers. Note incomplete
EXIT1  EQU  *          address decoding.
*
* P2 Now incremented until lsb zero => P2 = $0700
*
       USE  $0700,P2   P2 used as base for scratch pad
       SPC
       LDI  RAM/256    Initialise cursor images with
       ST   CURSHI     start of RAM.
       ST   ACURHI
       LDI  $00        Define port B as input
       ST   ODRB
       LDI  $FF        Define port A as output
       ST   ODRA
       LDI  $3E
       ST   (P2)
       SPC
LDCURS LD   CURSHI     Load P1 with current cursor
       XPAH P1
       LD   CURSLO
       XPAL P1
       SPC
NXTKEY LDI  GETKEY-1/256 Load P3 with entry point of
       XPAH P3         subroutine GETKEY
       LDI  GETKEY-1
       XPAL P3         P3 := $033A
       SPC
NXTNIB XPPC P3         Get a keystroke
       SPC
       LD   CURSPC
       RR
       RR
       RR
       RR
       XAE
       LDI  $01
       ANE
       JNZ  NOTDIG
       SPC
*
* Number key
*
       ILD  ENDAC      Increment count of number keys
       ANI  $01        If even the second digit of pair
       JZ   SECDIG
*
* First nibble
*
       XAE             Store first nibble at cursor
       ST   (P1)
       JMP  NXTNIB     Branch to get second nibble
       SPC
*
* Second nibble
*
SECDIG LD   STATIM     Load status from status image
       CAS             to set F0 and propagate cursor
       LD   (P1)       Load byte under cursor and OR
       OR   CURSPC     with new key
       ST   1(P1)+     Store both nibbles and increment
*                      cursor address
       JMP  NXTNIB     Jump to get next key stroke
       SPC
NOTDIG LDI  $00        Clear count of hex digits
       ST   ENDAC
       SPC
       LDI  $21        Check for EX key
       XRE
       JNZ  NOTEX
       SPC
*
* Execute stored program starting at current cursor
*
       LD   -1(P1)+
       LD   SUBRHI
       XPAH P3
       LD   SUBRLO
       XPAL P3
       LD   STATIM
       CAS
       LD   EXTIM
       XAE
       LD   ACCIM
       XPPC P1
       ST   ACCIM
       XAE
       ST   EXTIM
       CSA
       ST   STATIM
       XPAL P3
       ST   SUBRLO
       XPAH P3
       ST   SUBRHI
NXTKY1 JMP  NXTKEY
       SPC
NOTEX  LDI  $11        Check for -> key
       XRE
       JNZ  NOTFOR
       SPC
*
* Move cursor forwards
*
       CAS             Load status with zero so that
       LD   (P1)       F0 clears old cursor
       ST   1(P1)+     Increment P1, the cursor pointer
NXTKY2 JMP  NXTKY1     Jump to get next keystroke
       SPC
NOTFOR LDI  $01        Check for <- key
       XRE
       JNZ  NOTBAC
       SPC
*
* Move cursor back
*
       LD   STATIM     Load status image so that cursor
       CAS             will propagate if F0 set
       LD   (P1)       Clear present cursor if necessary
       ST   (P1)
       LD   -1(P1)+    Decrement P1, the cursor pointer
       JMP  NXTKY2     Jump to get next keystroke
       SPC
*
* Shift key
*
NOTBAC LDI  $FF        Set mode flag to FF.
       ST   MODEF
       XPPC P3         Get another key.
       LD   CURSPC
       JZ   NOTREP
       XAE
       SPC
       LDI  $13
       XRE
       JNZ  NOTSFT
       SPC
*
* second shift or exit - clear all spurious
*                        cursors
*
NOTREP LDI  $00
       ST   MODEF      Set mode flag back to zero
       CAS
       XPAL P1
       LDI  RAM/256
       XPAH P1
LOOP2  LD   (P1)
       ST   1(P1)+     Clear cursor
       XPAH P1
       JZ   LDCUR1
       XPAH P1
       JMP  LOOP2
LDCUR1 LD   CURSHI
       XPAH P1
       LD   CURSLO
       XPAL P1
NXTKY3 JMP  NXTKY2
       SPC
NOTSFT LDI  $0F
       XRE
       JNZ  NOTCLR
       SPC
*
* Clear
*
LOOP3  LDI  $FF
       ST   1(P1)+     Why not loop to here?
       XPAH P1
       JZ   LDCUR1
       XPAH P1
       JMP  LOOP3
       SPC
NOTCLR LDI  $01
       XRE
       JNZ  NOTDEF
       SPC
*
* Define
*
STCURS XPAH P1         store current cursor in
       ST   ACURHI     alternate cursor image
       XPAH P1
       XPAL P1
       ST   ACURLO
       XPAL P1
NOTRP1 JMP  NOTREP
       SPC
NOTDEF LDI  $02
       XRE
       JNZ  NOTRMB
*
* Define block of data
*
       LDI  $01        Set F0 in status image so that
       ST   STATIM     backward moves propagate cursor
*                      showing block on screen
       JMP  STCURS     Jump to copy current cursor into
*                      alternate cursor marking end of
*                      block
       SPC
NOTRMB LDI  $03
       XRE
       JNZ  NOTSTR
       SPC
*
*
*
LOOP4  XPPC P3
       LD   CURSPC
       XAE
       LDI  $11
       XRE
       JNZ  SKIP12
       SPC
       ILD  CURDIF
       XAE
       LD   $80(P1)    Note disp = ext contents
       ST   MODEF
LOOP5  LDI  $01
       CAS
       DLD  CURDIF
       XAE
       LD   $80(P1)    Note disp = ext contents
       XAE
       ADI  $01
       XAE
       ST   $80(P1)    Note disp = ext contents
       XAE
       JNZ  LOOP5
       SPC
       CAS
       NOP
       LD   MODEF
       ST   1(P1)+
       ILD  ACURLO
       JMP  LOOP4
       SPC
SKIP12 LDI  $10
       XRE
       JZ   SKIP13
LOOP8  LDI  $00
       ST   STATIM
       JMP  NOTRP1
       SPC
SKIP13 LD   -1(P1)
       ST   MODEF
       ILD  CURDIF
       LDI  $00
       XAE
LOOP13 LDI  $01
       CAS
       LD   $80(P1)    Note disp = ext contents
       XAE
       ADI  $FF
       XAE
       ST   $80(P1)    Note disp = ext contents
       CCL
       XAE
       ADI  $02
       XAE
       LD   CURDIF
       XRE
       JNZ  LOOP13
       CAS
       DLD  CURDIF
       XAE
       LD   MODEF
       ST   $80(P1)    Note disp = ext contents
       DLD  ACURLO
       LD   -1(P1)+
       JMP  LOOP4
       SPC
NOTSTR LDI  $04
       XRE
       JNZ  NOTMOV
       SPC
*
*
*
       XAE
       ILD  CURDIF
LOOP7  LD   $80(P1)    Note disp = ext contents
       XAE
       CCL
       ADI  $01
       XAE
       ST   $80(P2)    Note disp = ext contents
       LD   CURDIF
       XRE
       JNZ  LOOP7
       XAE
       ST   SCPLEN
       ILD  CURDIF
       XAE
       LDI  $90
       ST   $80(P2)    Note disp = ext contents
       ILD  CURDIF
       XAE
       LDI  $00
       CAS
       CAD  CURDIF
       ST   $80(P2)    Note disp = ext contents
LOOP8A JMP  LOOP8
       SPC
NOTMOV LDI  $0E
       XRE
       JNZ  NOTSWP
       SPC
*
* Exchange cursors
*
       LD   ACURHI
       ST   CURSHI
       LD   ACURLO
       ST   CURSLO
       XPAH P1
       ST   ACURHI
       XPAL P1
       ST   ACURLO
NXTKY5 JMP  LOOP8A
NOTSWP LDI  $12
       XRE
       JNZ  NOTRUN
       SPC
*
* Run (Routine in scratch pad)
*
       XPPC P2
       JMP  NXTKY5
       SPC
NOTRUN LDI  $0D
       XRE
       JNZ  NOTMCH
       SPC
*
* Match
*
       XPPC P3
       LD   CURSPC
       RR
       RR
       RR
       RR
       XAE
       LDI  $01
       ANE
LOOP9  JNZ  LOOP8A-1   ???????????????????
       XAE
       ST   MBYTE
       XPPC P3
       LD   CURSPC
       XAE
       LDI  $10
       ANE
       JNZ  LOOP9
       LD   MBYTE
       ORE
       ST   MBYTE
       XAE
       LDI  RAM/256
       XPAH P1
       LDI  RAM
       XPAL P1
LOOP10 LD   1(P1)+
       XRE
       JNZ  SKIP18
       LDI  01
       CAS
       LD   -1(P1)
       ST   -1(P1)
       LDI  $00
       CAS
SKIP18 XPAH P1
       JZ   EXIT14
       XPAH P1
       JMP  LOOP10
       SPC
NOTMCH LDI  $05
       XRE
       JNZ  NOTINS
       SPC
*
* Insert
*
       XAE             Set extension to zero
LOOP11 LD   SCPLEN     Compare extension with scratch
       XRE             length
       JZ   EXIT11     Jump out of loop if complete
       XAE             Increment offset in extension
       CCL
       ADI  $01
       XAE
       LD   $80(P2)    Load scratchpad byte
       ST   1(P1)+     Store in ram incrementing cursor
       JMP  LOOP11     Loop to copy next byte
       SPC
EXIT11 LDI  NXTKEY-1   Load P3 with address of NXTKEY
       XPAL P3         (-1) to allow return
       LDI  NXTKEY-1/256
       XPAH P3
       XPPC P3         Jump back to get next keystroke
       SPC
NOTINS LDI  RAM/256
       XPAH P1
       LDI  RAM
       XPAL P1
       LDI  $00
       XPAL P3
       SPC
       LDI  $0C
       XRE
       JNZ  NOTCPY
       SPC
*
*
*
       LDI  EPROM/256
       XPAH P3
LOOP12 LD   1(P3)+
       ST   1(P1)+
       XPAH P1
       JZ   SKIP22
       XPAH P1
       JMP  LOOP12
       SPC
NOTCPY LDI  $0A
       XRE
       JNZ  NOTCMP
       SPC
*
* Compare programmed EPROM with RAM
*
SKIP22 ST   MODEF      Clear error count in MODEF
       LDI  RAM/256    Load P1 with address of start
       XPAH P1         of RAM
       LDI  RAM
       XPAL P1
       LDI  EPROM/256  Load P3 with address of start
       XPAH P3         of ZIF EPROM
       LDI  EPROM
       XPAL P3
LOOP14 LD   1(P3)+     Compare RAM and EPROM bytes and
       XOR  1(P1)+     increment their pointers
       JNZ  SKIP24
CHKE14 XPAH P1         Check for end of RAM reached
       JZ   EXIT14
       XPAH P1
       JMP  LOOP14     Loop for next comparason
SKIP24 LDI  $01        Bytes are different.
       CAS             Load F0 in status with 1
       LD   -1(P1)     Mark differing byte with cursor
       ST   -1(P1)
       LDI  $00        Clear F0 in status
       CAS
       ILD  MODEF      Increment error count in MODEF
       JMP  CHKE14     Jump back to check end of loop
EXIT14 LDI  LDCURS-1
       XPAL P3
       LDI  LDCURS-1/256
       XPAH P3
       XPPC P3
       SPC
NOTCMP LDI  $0B
       XRE
       JNZ  NOTBLW
*
* Blow EPROM
*
       LDI  $00        initialise cycle count to 0
LOOP16 ST   MODEF      Store new cycle count
       DLY  $FF
       DLY  $FF
       LDI  $02
       CAS
       LDI  EPROM/256
       XPAH P3
       LDI  RAM/256
       XPAH P1
LOOP15 LD   1(P1)+
       ST   0(P3)+     ??????
       LD   1(P3)+
       XPAH P1
       JZ   EXIT15
       XPAH P1
       JMP  LOOP15
EXIT15 CAS
       DLY  $FF
       LD   MODEF
       DAI  $01
       JNZ  LOOP16
       JMP  SKIP22
       SPC
NOTBLW LDI  $07
       XRE
       JNZ  NOTDMP
       SPC
*
* Dump ram on to cassette
*
       LDI  $E1
       XPAL P3
       LDI  $20
       ST   MODEF
       LDI  $AA
       ST   CURDIF
LOOP17 LD   MODEF
       JZ   SKIP28
       LDI  $AA
       XAE
       DLD  MODEF
       JNZ  SKIP29
       LDI  $69
       XAE
SKIP29 JMP  SKIP30
SKIP28 LD   1(P1)+
       XAE
       LD   CURDIF
       XRE
       ST   CURDIF
SKIP30 XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       DLY  $00
       XPPC P3
       XPAH P1
       JZ   EXIT17
       XPAH P1
       JMP  LOOP17
EXIT17 XPAH P1
       LD   MODEF
       JNZ  SKIP32
       LDI  $AA
       ST   MODEF
       LD   CURDIF
       XAE
       JMP  SKIP30
SKIP32 LDI  LDCURS-1
       XPAL P3
       LDI  LDCURS-1/256
       XPAH P3
       XPPC P3
       SPC
NOTDMP LDI  $08
       XRE
       JNZ  NOTRCL
       SPC
*
* Recall ram from cassette
*
       LDI  $CE
       XPAL P3
LOOP18 LDI  $30
       ST   MODEF
LOOP19 XPPC P3
       LDI  $AA
       XRE
       JZ   EXIT18
       LDI  $55
       XRE
       JNZ  LOOP18
EXIT18 DLD  MODEF
       JNZ  LOOP19
LOOP20 XPPC P3
       LDI  $69
       XRE
       JNZ  LOOP20
LOOP21 XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       ST   1(P1)+
       XPAH P1
       JZ   EXIT21
       XPAH P1
       JMP  LOOP21
EXIT21 LDI  $0C
       XPAH P1
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
       XPPC P3
LOOP22 XOR  1(P1)+
       XPAH P1
       JZ   EXIT22
       XPAH P1
       JMP  LOOP22
EXIT22 XPAH P1
       ST   MODEF
NXTKY9 JMP  SKIP32
       SPC
NOTRCL LDI  $06
       XRE
       JNZ  NOTCAL
       SPC
*
* Execute program in ZIF EPROM
*
       LDI  EPROM/256
       XPAH P3
       LDI  EPROM
       XPAL P3
       XPPC P3
       SPC
NOTCAL LDI  $09
       XRE
       JNZ  NXTKY9
*
* Copy from Firmware
*
       LDI  RAM
       XPAL P1
       LDI  SYSTEM/256
       XPAL P3
       LDI  SYSTEM
       XPAH P3
       LDI  RAM/256
       XPAH P1
LOOP23 LD   1(P3)+
       ST   1(P1)+
       XPAH P1
       JZ   NXTKY9
       XPAH P1
       JMP  LOOP23
       PAGE
GETRET XPPC P3
GETKEY XPAH P1         Store MSB of cursor in display
       ST   CURSHI     area and restore to P1
       XPAH P1
       SPC
       LD   CURSHI     Load bit 0 of Port A with bit 1
       SR              of MSB of cursor to select display
       ST   PORTA      page.
       SPC
       LDI  $81        Set carry for subtract and F0
       CAS             to mark cursor in display
       XPAL P1         Store LSB of cursor in display
       ST   CURSLO     area and copy into extension
       XAE
       LD   ACURLO     Load up LSB of alternate cursor
       CAE             subtract from current cursor and
       ST   CURDIF     store in cursor difference display
       XAE             Restore cursor LSB to P1
       XPAL P1
       LD   (P1)       Mark cursor position on display
       ST   (P1)
       SPC
       LD   CURSPC     Load cursor speed into extension
       XAE
       LDI  $10        Compare with $10
       XRE
       JZ   SKIP37
       LDI  $11        Compare with $11
       XRE
       JNZ  SKIP38
       SPC
SKIP37 EQU  *          Here if CURSPC>=16
       ILD  KEYWD      increment count of times key
       XAE             generated and store in extension
       LDI  $F0
       ANE
       JZ   SKIP39
       LDI  $0F
       ANE
       JZ   SKIP39
       ORI  $30
       ST   KEYWD
       SPC
GETRT1 JMP  GETRET
       SPC
SKIP39 DLY  $FF
       DLY  $FF
       LD   PORTB
       XRI  $FF
       JNZ  GETRET
SKIP38 LD   PORTB
       XRI  $FF
       XAE
       DLY  $20
       LD   PORTB
       XRI  $FF
       ORE
       JNZ  SKIP38
LOOP24 LDI  $04
       CAS
       LDI  $00
       ST   KEYWD
       LDI  $00
       CAS
       ST   CURSPC
       LD   PORTB
       XRI  $FF
       XAE
       DLY  $20
       LD   PORTB
       XRI  $FF
LOOP26 ANE
       JZ   LOOP24
LOOP27 SR
       JZ   EXIT27
       XAE
       ILD  CURSPC
       XAE
       JMP  LOOP27
EXIT27 LDI  $98
       ST   MODEF
LOOP29 DLD  MODEF
       XAE
       LDI  $92
       XRE
       JZ   LOOP24
       ST   $80(P2)
       LD   PORTB
       XRI  $FF
       JZ   GETRT1
       CCL
       LD   CURSPC
       ADI  $07
       ST   CURSPC
       JMP  LOOP29
       PAGE/
LISRET XPPC P3
LISTEN CSA
       ANI  $20
       JNZ  LISTEN
LOOP28 CSA
       ANI  $20
       JZ   LOOP28
       LDI  $60
       DLY  $00
       SIO
       LDE
       JMP  LISRET
       SPC  5
TLKRET XPPC P3
TALK   LDI  $01
       ANE
       SIO
       JZ   SKIP41
       LDI  $38
       DLY  $00
       LDI  $00
       XAE
       SIO
       XAE
       LDI  $4D
       DLY  $00
SKIP41 LDI  $50
       DLY  $00
       XAE
       SIO
       XAE
       LDI  $40
       JMP  TLKRET
       PAGE
       ORG  $06A0
PORTA  RMB  1
PORTB  RMB  1
ODRA   RMB  1
ODRB   RMB  1
MDR    RMB  1
       ORG  $0700
SCPAD  RMB  108
       RMB  3
SCPLEN RMB  1
CURSHI RMB  1
CURSLO RMB  1
ACURHI RMB  1
ACURLO RMB  1
SUBRHI RMB  1
SUBRLO RMB  1
ACCIM  RMB  1
EXTIM  RMB  1
STATIM RMB  1
PPWORD RMB  1
MBYTE  RMB  1
CURSPC RMB  1
KEYWD  RMB  1
ENDAC  RMB  1
CURDIF RMB  1
MODEF  RMB  1
       ORG  $0800
EPROM  RMB  $0400
RAM    RMB  $0400
       END
