;--------------------------------------------------------------------------------------------------------
;-
;- Name:            rfs_bank8.asm
;- Created:         July 2019
;- Author(s):       Philip Smart
;- Description:     Sharp MZ series Rom Filing System.
;-                  This assembly language program is written to utilise the banked flashroms added with
;-                  the MZ-80A RFS hardware upgrade.
;-
;- Credits:         
;- Copyright:       (c) 2018-2026 Philip Smart <philip.smart@net2net.org>
;-
;- History:         July 2019 - Merged 2 utilities to create this compilation.
;-                  May 2020  - Bank switch changes with release of v2 pcb with coded latch. The coded
;-                              latch adds additional instruction overhead as the control latches share
;-                              the same address space as the Flash RAMS thus the extra hardware to
;-                              only enable the control registers if a fixed number of reads is made
;-                              into the upper 8 bytes which normally wouldnt occur. Caveat - ensure
;-                              that no loop instruction is ever placed into EFF8H - EFFFH.
;-                  Aug 2023  - Updates to make RFS run under the SFD700 Floppy Disk Interface board.
;-                              UROM remains the same, a 2K paged ROM, MROM is located at F000 when
;-                              RFS is built for the SFD700.
;-
;--------------------------------------------------------------------------------------------------------
;- This source file is free software: you can redistribute it and-or modify
;- it under the terms of the GNU General Public License as published
;- by the Free Software Foundation, either version 3 of the License, or
;- (at your option) any later version.
;-
;- This source file is distributed in the hope that it will be useful,
;- but WITHOUT ANY WARRANTY; without even the implied warranty of
;- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;- GNU General Public License for more details.
;-
;- You should have received a copy of the GNU General Public License
;- along with this program.  If not, see <http://www.gnu.org/licenses/>.
;--------------------------------------------------------------------------------------------------------

            ;===========================================================
            ;
            ; USER ROM BANK 8 - 
            ;
            ;===========================================================
            ORG     UROMADDR

            ;--------------------------------
            ; Common code spanning all banks.
            ;--------------------------------
            NOP
            HWSELROM2                                                        ; Select the first ROM page.
            ;
            ; No mans land... this should have switched to Bank 0 and at this point there is a jump to 00000H.
            JP      00000H                                                   ; This is for safety!!


            ;------------------------------------------------------------------------------------------
            ; Bank switching code, allows a call to code in another bank.
            ; This code is duplicated in each bank such that a bank switch doesnt affect logic flow.
            ;------------------------------------------------------------------------------------------            
            ALIGN_NOPS UROMBSTBL
            ;
BKSW8to0:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK0                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to1:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK1                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to2:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK2                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to3:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK3                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to4:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK4                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to5:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK5                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to6:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK6                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to7:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK7                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to8:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK8                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to9:   PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK9                                              ; Required bank to call.
            JR      BKSW8_0
BKSW8to10:  PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK10                                             ; Required bank to call.
            JR      BKSW8_0
BKSW8to11:  PUSH    AF
            LD      A, ROMBANK8                                              ; Calling bank (ie. us).
            PUSH    AF
            LD      A, ROMBANK11                                             ; Required bank to call.
            ;
BKSW8_0:    PUSH    HL                                                       ; Place function to call on stack
            LD      HL, BKSWRET8                                             ; Place bank switchers return address on stack.
            EX      (SP),HL
            LD      (TMPSTACKP),SP                                           ; Save the stack pointer as some old code corrupts it.
            BNKSWSEL
            JP      (HL)                                                     ; Jump to required function.
BKSWRET8:   POP     AF                                                       ; Get bank which called us.
            BNKSWSELRET
            POP     AF
            RET  

            ;-------------------------------------------------------------------------------
            ; START OF METHODS
            ;-------------------------------------------------------------------------------

            IF      BUILD_ROMDISK+BUILD_PICOZ80 = 1

            ; Work RAM addresses (must match rfs_bank7.asm layout at 0xCF00)
OPCD_MROMBNK_8: EQU  0CF3BH           ; Same address as OPCD_MROMBNK in bank 7
DSMFINDOPCD_MROM_8: EQU  0E80H
ASMFINDINST_MROM_8: EQU  0F10H
ASMFINDPARM_MROM_8: EQU  0F70H
MROM_OPCD6_8: EQU  6
MROM_OPCD7_8: EQU  7

            ; Work RAM EQUs for variables defined with DS virtual in bank 7.
COUNT_C_8:  EQU     0CF00H
ADDR_8:     EQU     0CF01H
ADDR_LO_8:  EQU     0CF01H
ADDR_HI_8:  EQU     0CF02H
ASM_ADDR_8: EQU     0CF03H
ASM_BUF_8:  EQU     0CF0BH
OUT_BUF_8:  EQU     0CF17H
INS_BUF_8:  EQU     0CF1BH
PARM_BUF_8: EQU     0CF1FH
VAL_BUF_8:  EQU     0CF26H
VAL_BUF_HI_8: EQU   0CF26H
VAL_BUF_LO_8: EQU   0CF28H
SRC_ADDR_8: EQU     0CF2BH
DES_ADDR_8: EQU     0CF2DH
BLK_ADDR_8: EQU     0CF2FH
ROW_ADDR_8: EQU     0CF31H
BLK_NUM_8:  EQU     0CF33H
BLK_SIZE_8: EQU     0CF34H
ROW_NUM_8:  EQU     0CF35H
ML_BUF_8:   EQU     0CF36H
ML_BTCOUNT_8: EQU   0CF38H
VAL_LO_8:   EQU     0CF39H
VAL_HI_8:   EQU     0CF3AH
BUF_END_8:  EQU     0CF3BH

             ;******************************************************************
             ; ASM_MAIN  Z80 Assembler (picoZ80/RomDisk multi-bank)
             ;******************************************************************
ASM_MAIN:    CALL    HLHEX           ; Get address
             JP      C,ASM_ERR8
             LD      (ADDR_8),HL

ASM_LOOP1:   CALL    NL
             LD      A,(ADDR_HI_8)
             CALL    PRTHX
             LD      A,(ADDR_LO_8)
             CALL    PRTHX
             CALL    PRNTS

             LD      HL,ASM_BUF_8
             LD      B,30h
             CALL    MEMSET8

             LD      DE,BUFER
             CALL    GETL
             CALL    HLHEX
             JR      C,ASM_LOOP3
             LD      (ADDR_8),HL
ASM_LOOP3:   LD      BC,01005H
             LD      DE,BUFER+5
             LD      HL,ASM_BUF_8
             CALL    GETSTR8
             LD      A,0C2H
             CALL    DPCT

             ; Clear the line
             LD      A,(SCRNMODE)
             LD      B,39
             OR      A
             JR      Z,ASM_LOOP4
             LD      B,79
ASM_LOOP4:   CALL    PRNTS
             DJNZ    ASM_LOOP4

             ; Reprint the line
             LD      HL,(DSPXY)
             LD      L, 0
             LD      (DSPXY),HL
             LD      A,(ADDR_HI_8)
             CALL    PRTHX
             LD      A,(ADDR_LO_8)
             CALL    PRTHX
             CALL    PRNTS
             LD      DE,ASM_BUF_8
ASM_LOOP5:   LD      A,(DE)
             CP      000H
             JR      Z,ASM_LOOP6
             CALL    PRNT
             INC     DE
             JR      ASM_LOOP5

ASM_LOOP6:   LD      HL,(DSPXY)
             LD      L, 22
             LD      (DSPXY),HL

             LD      A,(ASM_BUF_8)
             CP      0
             JP      Z,ASM_EXIT8

ASM_CPYINS:  LD      DE,INS_BUF_8
             LD      HL,ASM_BUF_8
             CALL    CPY2SPC8
             CALL    SKIPSPC8

             LD      BC,PARM_BUF_8
             CALL    PADWSPC8

             LD      A,10h
             LD      B,A
GET_NEXTASM: LD      A,(HL)
             CP      0
             JP      Z,ASMLOOPEXIT
             CALL    ISFLAGORNUM8
             JP      NZ,SAVE_ASMCHR
             CALL    ASMGETVAL8
             LD      A,'*'
             LD      (DE),A
             INC     DE
             LD      A,(HL)

SAVE_ASMCHR: CP      0
             JP      Z,ASMLOOPEXIT
             LD      (DE),A
             INC     DE
             INC     HL
             DEC     B
             JP      NZ,GET_NEXTASM

ASMLOOPEXIT: LD      BC,VAL_BUF_8
             CALL    PADWSPC8

             LD      (SRC_ADDR_8),HL
             LD      (DES_ADDR_8),DE

             CALL    ASMFINDINST_WRAP
             LD      A,(BLK_SIZE_8)
             CP      0
             JP      NZ,ASM_FINDPRM
ASM_ERR_INS: LD      DE,MSGNOINSTR
             LD      HL,PRINTMSG
             CALL    BKSW8to6
             JP      ASM_LOOP1

ASM_FINDPRM: CALL    ASMFINDPARM_WRAP
             LD      A,(ML_BUF_8+2)
             CP      0
             JP      NZ,ASMOUTML
             LD      DE,MSGNOPARAM
             LD      HL,PRINTMSG
             CALL    BKSW8to6
             JP      ASM_LOOP1

ASMOUTML:    CALL    RTJUSTVAL8

             LD      DE,VAL_BUF_HI_8
             CALL    HLHEX
             JR      C, ASM_ERR_INS
             LD      A,H
             LD      (VAL_HI_8),A
             LD      A,L
             LD      (VAL_LO_8),A

             LD      IX,OUT_BUF_8
             LD      A,(ML_BUF_8+1)
             CP      0
             JP      Z,ASMNOBYTE2
             LD      (IX),A
             INC     IX
             CP      0CBh
             JP      NZ,ASMNOBYTE2
             LD      A,(ML_BUF_8)
             AND     0C0h
             JP      Z,ASMNOBYTE2
             LD      A,(ML_BUF_8)
             LD      B,A
             LD      A,(VAL_LO_8)
             SLA     A
             SLA     A
             SLA     A
             AND     38h
             OR      B
             LD      (ML_BUF_8),A

ASMNOBYTE2:  LD      A,(ML_BUF_8)
             LD      (IX),A
             INC     IX

             LD      A,(VAL_LO_8)
             LD      (IX),A
             INC     IX
             LD      A,(VAL_HI_8)
             LD      (IX),A

ASM_TOMEM:   LD      A,(ML_BTCOUNT_8)
             LD      B,A
             LD      IX,OUT_BUF_8
ASM_TOMEM1:  LD      HL,(ADDR_LO_8)
             LD      A,(IX)
             LD      (HL),A
             CALL    PRTHX
             CALL    PRNTS
             INC     HL
             LD      (ADDR_LO_8),HL
             INC     IX
             DEC     B
             JP      NZ,ASM_TOMEM1
             JP      ASM_LOOP1

ASM_EXIT8:   RET

ASM_ERR8:    LD      DE,MSGNOTFND
             LD      HL,PRINTMSG
             CALL    BKSW8to6
             RET

             ;******************************************************************
             ; ASMFINDINST_WRAP
             ; Search both MROM banks for instruction match.
             ; Saves matched bank in OPCD_MROMBNK.
             ;******************************************************************
ASMFINDINST_WRAP:
             LD      A,(ROMBK1)
             PUSH    AF
             LD      A,MROM_OPCD6_8
             LD      (BNKSELMROM),A
             CALL    ASMFINDINST_MROM_8
             LD      A,(BLK_SIZE_8)
             OR      A
             JR      NZ,AFIW_FND6
             LD      A,MROM_OPCD7_8
             LD      (BNKSELMROM),A
             CALL    ASMFINDINST_MROM_8
             LD      A,(BLK_SIZE_8)
             OR      A
             JR      NZ,AFIW_FND7
             POP     AF
             LD      (BNKSELMROM),A
             RET
AFIW_FND6:   LD      A,MROM_OPCD6_8
             LD      (OPCD_MROMBNK_8),A
             POP     AF
             LD      (BNKSELMROM),A
             RET
AFIW_FND7:   LD      A,MROM_OPCD7_8
             LD      (OPCD_MROMBNK_8),A
             POP     AF
             LD      (BNKSELMROM),A
             RET

             ;******************************************************************
             ; ASMFINDPARM_WRAP
             ; Select correct MROM bank and call ASMFINDPARM.
             ;******************************************************************
ASMFINDPARM_WRAP:
             LD      A,(ROMBK1)
             PUSH    AF
             LD      A,(OPCD_MROMBNK_8)
             LD      (BNKSELMROM),A
             CALL    ASMFINDPARM_MROM_8
             POP     AF
             LD      (BNKSELMROM),A
             RET

             ;******************************************************************
             ; Assembler utility routines (bank 8 local copies)
             ;******************************************************************

MEMSET8:     LD      (HL),A
             INC     HL
             DEC     B
             JP      NZ, MEMSET8
             RET

RTJUSTVAL8:  PUSH    IX
             PUSH    BC
             LD      IX,VAL_BUF_8
             LD      B,05h
RTJVAL_LP8:  LD      A,(IX+3)
             CP      ' '
             JP      NZ,RTJVAL_EX8
             LD      A,(IX+2)
             LD      (IX+3),A
             LD      A,(IX+1)
             LD      (IX+2),A
             LD      A,(IX+0)
             LD      (IX+1),A
             LD      A,'0'
             LD      (IX+0),A
             DEC     B
             JP      NZ,RTJVAL_LP8
RTJVAL_EX8:  POP     BC
             POP     IX
             RET

BYTE2ASCII8: LD      H,A
             RRA
             RRA
             RRA
             RRA
             CALL    NIB_TOHEX8
             LD      L,A
             LD      A,H
             CALL    NIB_TOHEX8
             LD      H,A
             RET

NIB_TOHEX8:  AND     0Fh
             CP      0Ah
             JP      M,ADD_30X8
             ADD     A,07h
ADD_30X8:    ADD     A,030h
             RET

IS_DIGIT8:   CALL    ISDECDIGIT8
             JP      Z,IS_DIG_EX8
             CALL    ISHEXDIGIT8
IS_DIG_EX8:  RET

ISHEXDIGIT8: CP      'A'
             JP      M,ISHEXD_EX8
             CP      'G'
             JP      M,ISHEXD_ZR8
             JP      ISHEXD_EX8
ISHEXD_ZR8:  CP      A
             RET
ISHEXD_EX8:  CP      0
             RET

ISDECDIGIT8: CP      '0'
             JP      M,ISDECD_EX8
             CP      03Ah
             JP      M,ISDECD_ZR8
             JP      ISDECD_EX8
ISDECD_ZR8:  CP      A
             RET
ISDECD_EX8:  CP      0
             RET

GETSTR8:     LD      A,(DE)
             CP      33
             JR      NC, GSTR1_8
             CP      00DH
             JR      Z, GSTR2_8
             OR      A
             JR      Z, GSTR2_8
             INC     DE
             INC     C
             JR      GETSTR8
GSTR1_8:     LD      (HL),A
             INC     DE
             INC     HL
             INC     C
             LD      A,(DE)
             CP      00DH
             JR      Z,GSTR2_8
             DJNZ    GSTR1_8
GSTR2_8:     XOR     A
             LD      (HL),A
             RET

ASMGETVAL8:  PUSH    DE
             PUSH    BC
             LD      DE,VAL_BUF_8
             LD      B,05h
ASMGVL_LP8: LD      A,(HL)
             CP      0
             JP      Z,ASMGVL_EX8
             CALL    ISVALFLAG8
             JP      Z,ASMGVL_SK8
             CALL    IS_DIGIT8
             JP      NZ,ASMGVL_EX8
             LD      (DE),A
             INC     DE
ASMGVL_SK8:  INC     HL
             DEC     B
             JP      NZ,ASMGVL_LP8
ASMGVL_EX8:  POP     BC
             POP     DE
             RET

ISFLAGORNUM8:CALL    ISVALFLAG8
             JP      Z,ISNUMF_ZR8
             CALL    ISDECDIGIT8
ISNUMF_ZR8:  RET

ISVALFLAG8:  CP      '$'
             JP      Z,ISVALF_ZR8
             CP      '+'
             JP      Z,ISVALF_ZR8
             CP      '#'
             JP      Z,ISVALF_ZR8
             CP      0
ISVALF_ZR8:  RET

PADWSPC8:    LD      A,B
             CP      D
             JP      NZ,DOPADWSP8
             LD      A,C
             CP      E
             JP      M,PADWSP_EX8
             JP      NZ,DOPADWSP8
PADWSP_EX8:  RET
DOPADWSP8:   LD      A,' '
             LD      (DE),A
             INC     DE
             JP      PADWSPC8

SKIPSPC8:    LD      B,10h
SKIPSP_LP8:  LD      A,(HL)
             INC     HL
             CP      ' '
             JP      Z,SKIPSP_EX8
             CP      0
             JP      Z,SKIPSP_EX8
             DEC     B
             JP      NZ,SKIPSP_LP8
SKIPSP_EX8:  RET

CPY2SPC8:    LD      B,0Ch
CPY2SP_LP8:  LD      A,(HL)
             CP      ' '
             JP      Z,CPY2SP_EX8
             CP      0
             JP      NZ,CPY2SP_CP8
             LD      A,' '
             LD      (HL),A
             INC     HL
             LD      A,0
             LD      (HL),A
             DEC     HL
             JP      CPY2SP_EX8
CPY2SP_CP8:  LD      (DE),A
             INC     DE
             INC     HL
             DEC     B
             JP      NZ,CPY2SP_LP8
CPY2SP_EX8:  RET

            ENDIF                    ; BUILD_ROMDISK+BUILD_PICOZ80

            ;-------------------------------------------------------------------------------
            ; END OF METHODS
            ;-------------------------------------------------------------------------------

            ; RomDisk - Pad to EFFF boundary.
            IF      BUILD_ROMDISK+BUILD_PICOZ80 = 1
              ALIGN 0EFF8h
              ORG   0EFF8h
              DB    0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh            
            ENDIF
            ; SFD700 - Pad to 10000H
            IF      BUILD_SFD700 = 1
              ALIGN 10000H
            ENDIF
