Files
RFS/asm/rfs_bank8.asm

941 lines
30 KiB
NASM

;--------------------------------------------------------------------------------------------------------
;-
;- 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/>.
;--------------------------------------------------------------------------------------------------------
IF BUILD_SFD700 = 1
ORG 0E000H
ALIGN 0E300H
DB "BANK8"
ALIGN UROMADDR
ENDIF
;===========================================================
;
; 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
;-------------------------------------------------------------------------------
;===============================================================================
; MZ-80A FLOPPY DISK CONTROLLER (SFD700) — Bank 8 (8K: E300-FFFF).
;
; Hardware-accelerated read using A10 address toggle:
; F3FE: DD E9 = JP (IX) — spin loop (A10=0, DRQ low).
; F7FE: FD E9 = JP (IY) — data handler (A10=1, DRQ high).
; These are the ORIGINAL MZ-80A FI ROM addresses that BASIC expects.
;
; Bank 8 = ROMBANK8 = 12 (>= ROMBANK6), so E-page + F-page are both mapped.
;===============================================================================
IF BUILD_SFD700 = 1
; MZ-80A specific data.
DSKID80A: DB 002H, "IPLPRO"
PRMBLK80A: DB 000H, 000H, 000H, 000H, 001H, 000H, 0CEH, 000H, 000H, 000H, 000H
ERRTONE8: DB "A0", 0D7H, "ARA", 0D7H, "AR", 00DH
FD80A_TSP EQU 0101EH ; In RAM, not ROM.
ENDIF
; Glass: label outside IF for global visibility.
FD80A_BOOT:
IF BUILD_SFD700 = 1
PUSH DE
LD DE,BPARA
LD HL,PRMBLK80A
LD BC,11
LDIR
POP DE
LD A,(DE)
CP 00DH
JR NZ,FD80A_GDSK
CALL FD80A_INIT
FD80A_PRM: LDDE MSGBOOTDRV
LD HL,PRINTMSG
CALL BKSW8to6
LD DE,011A3H
CALL GETL
LD A,(DE)
CP 01BH
JP Z,FD80A_BRK
LD HL,19
ADD HL,DE
LD A,(HL)
CP 00DH
JR Z,FD80A_RD1
FD80A_GDSK: CALL HEX
JR C,FD80A_PRM
DEC A
CP 004H
JR NC,FD80A_PRM
LD (BPARA),A
FD80A_RD1: LD IX,BPARA
CALL FD80A_READ
LD HL,0CE00H
LD DE,DSKID80A
LD B,007H
FD80A_CHK: LD C,(HL)
LD A,(DE)
CP C
JP NZ,FD80A_NMS
INC HL
INC DE
DJNZ FD80A_CHK
LDDE MSGIPLLOAD
LD HL,PRINTMSG
CALL BKSW8to6
LD DE,0CE07H
LD HL,PRTFN
CALL BKSW8to6
LD IX,BPARA
LD HL,(0CE16H)
LD (IX+5),L
LD (IX+6),H
LD HL,(0CE14H)
LD (IX+3),L
LD (IX+4),H
LD HL,(0CE1EH)
LD (IX+1),L
LD (IX+2),H
CALL FD80A_READ
CALL FD80A_INIT
LD HL,(0CE18H)
JP (HL)
FD80A_LERR: LDDE MSGLOADERR
JR FD80A_ERR
FD80A_NMS: LDDE MSGDSKNOTMST
FD80A_ERR: LD HL,(TMPSTACKP)
LD (FD80A_TSP),HL
LD HL,PRINTMSG
CALL BKSW8to6
LD DE,ERRTONE8
CALL MELDY
LD HL,(FD80A_TSP)
LD SP,HL
RET
FD80A_BRK: LD SP,(TMPSTACKP)
RET
; --- Low-level FDC routines ---
FD80A_RDY: LD A,(MOTON)
RRCA
CALL NC,FD80A_MON
LD A,(IX+0)
OR 084H
OUT (FDC_DRIVE),A
XOR A
LD (FDCCMD),A
LD HL,0
FD80A_RDW: DEC HL
LD A,H
OR L
JP Z,FD80A_DSKE
IN A,(FDC_CMD)
CPL
RLCA
JR C,FD80A_RDW
LD C,(IX+0)
LD HL,TRK0FD1
LD B,0
ADD HL,BC
BIT 0,(HL)
RET NZ
CALL FD80A_SK0
SET 0,(HL)
RET
FD80A_MON: LD A,080H
OUT (FDC_DRIVE),A
LD B,16
FD80A_MNW: CALL FD80A_DL60
DJNZ FD80A_MNW
LD A,1
LD (MOTON),A
RET
FD80A_SEEK: LD A,01BH
CALL FD80A_CMD
AND 099H
RET
FD80A_INIT: XOR A
OUT (FDC_DRIVE),A
LD (TRK0FD1),A
LD (TRK0FD2),A
LD (TRK0FD3),A
LD (TRK0FD4),A
LD (MOTON),A
RET
FD80A_SK0: LD A,00BH
CALL FD80A_CMD
AND 085H
XOR 004H
RET Z
JP FD80A_DSKE
FD80A_CMD: LD (FDCCMD),A
CPL
OUT (FDC_CMD),A
CALL FD80A_WBR
IN A,(FDC_CMD)
CPL
RET
FD80A_WBR: PUSH DE
PUSH HL
CALL FD80A_DL7
LD E,7
FD80A_WB1: LD HL,0
FD80A_WB2: DEC HL
LD A,H
OR L
JR Z,FD80A_WB3
IN A,(FDC_CMD)
CPL
RRCA
JR C,FD80A_WB2
POP HL
POP DE
RET
FD80A_WB3: DEC E
JR NZ,FD80A_WB1
POP HL
POP DE
JP FD80A_DSKE
FD80A_WBA: PUSH DE
PUSH HL
CALL FD80A_DL7
LD E,7
FD80A_WA1: LD HL,0
FD80A_WA2: DEC HL
LD A,H
OR L
JR Z,FD80A_WA3
IN A,(FDC_CMD)
CPL
RRCA
JR NC,FD80A_WA2
POP HL
POP DE
RET
FD80A_WA3: DEC E
JR NZ,FD80A_WA1
POP HL
POP DE
JP FD80A_DSKE
; --- Hardware-accelerated sector read ---
; Uses A10 toggle: F3FE=JP(IX) spin, F7FE=JP(IY) data.
FD80A_READ: CALL FD80A_CNV
FD80A_R1: CALL FD80A_PRS
FD80A_R2: CALL FD80A_SID
CALL FD80A_SEEK
JR NZ,FD80A_RET
CALL FD80A_STR
PUSH IX
LD IX,0F3FEH ; Spin loop at F3FE (original FI ROM addr).
LD IY,FD80A_INI ; Data handler.
LD A,094H
CALL FD80A_CM2
FD80A_R3: LD B,0
JP (IX) ; Enter spin loop.
FD80A_INI: INI
JP NZ,0F3FEH ; Back to spin loop.
POP IX
INC (IX+8)
LD A,(IX+8)
PUSH IX
LD IX,0F3FEH
CP 17
JR Z,FD80A_SEC
DEC D
JR NZ,FD80A_R3
JR FD80A_RDN
FD80A_SEC: DEC D
FD80A_RDN: CALL FD80A_FI
POP IX
IN A,(FDC_CMD)
CPL
AND 0FFH
JR NZ,FD80A_RET
CALL FD80A_ADJ
JP Z,FD80A_END
LD A,(IX+7)
JR FD80A_R2
FD80A_RET: LD A,(RETRIES)
DEC A
LD (RETRIES),A
JP Z,FD80A_DSKE
CALL FD80A_SK0
JR FD80A_R1
FD80A_END: LD A,080H
OUT (FDC_DRIVE),A
RET
; --- Helpers ---
FD80A_PRS: CALL FD80A_RDY
LD D,(IX+4)
LD A,(IX+3)
OR A
JR Z,FD80A_PS1
INC D
FD80A_PS1: LD A,(IX+10)
LD (IX+8),A
LD A,(IX+9)
LD (IX+7),A
LD L,(IX+5)
LD H,(IX+6)
RET
FD80A_SID: SRL A
CPL
OUT (FDC_DATA),A
JR NC,FD80A_S0
LD A,1
JR FD80A_S1
FD80A_S0: XOR A
FD80A_S1: CPL
OUT (FDC_SIDE),A
RET
FD80A_STR: LD C,FDC_DATA
LD A,(IX+7)
SRL A
CPL
OUT (FDC_TRACK),A
LD A,(IX+8)
CPL
OUT (FDC_SECTOR),A
RET
FD80A_ADJ: LD A,(IX+8)
CP 17
JR NZ,FD80A_AJ1
LD A,1
LD (IX+8),A
INC (IX+7)
FD80A_AJ1: LD A,D
OR A
RET
FD80A_CNV: LD B,0
LD DE,16
LD L,(IX+1)
LD H,(IX+2)
XOR A
FD80A_CN1: SBC HL,DE
JR C,FD80A_CN2
INC B
JR FD80A_CN1
FD80A_CN2: ADD HL,DE
LD H,B
INC L
LD (IX+9),H
LD (IX+10),L
LD A,10
LD (RETRIES),A
RET
FD80A_CM2: LD (FDCCMD),A
CPL
OUT (FDC_CMD),A
CALL FD80A_WBA
RET
FD80A_FI: LD A,0D8H
CPL
OUT (FDC_CMD),A
CALL FD80A_WBR
RET
FD80A_DSKE: CALL FD80A_INIT
JP FD80A_LERR
FD80A_DL7: PUSH DE
LD DE,7
JR FD80A_DLP
FD80A_DL60: PUSH DE
LD DE,01013H
FD80A_DLP: DEC DE
LD A,E
OR D
JR NZ,FD80A_DLP
POP DE
RET
; --- Hardware acceleration alignment points (F-page) ---
; JP (IX) at F3FE: A10=0, DRQ low spin loop.
ALIGN_NOPS 0F3FEH
JP (IX) ; DD E9 at F3FE/F3FF.
; JP (IY) at F7FE: A10=1, DRQ high data handler.
ALIGN_NOPS 0F7FEH
JP (IY) ; FD E9 at F7FE/F7FF.
; SFD700 - Pad to end of 8K bank (F-page through FFFFH).
ALIGN 10000H
ENDIF ; BUILD_SFD700
; 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