; MP/M 2 XIOS for Z80-Simulator ; ; Copyright (C) 1989-2006 by Udo Munk ; ; This XIOS is a patch for z80pack versions 1.8 and 1.9, banking doesn't ; work correct with the XIOS included in that versions. For all later ; versions don't use this, the problem is fixed already. ; .Z80 CSEG ; ; i/o ports ; CONSTA EQU 0 ;console status port CONDAT EQU 1 ;console data port PRTSTA EQU 2 ;printer status port PRTDAT EQU 3 ;printer data port AUXSTA EQU 4 ;auxilary status port AUXDAT EQU 5 ;auxilary data port FDCD EQU 10 ;fdc-port: # of drive FDCT EQU 11 ;fdc-port: # of track FDCS EQU 12 ;fdc-port: # of sector FDCOP EQU 13 ;fdc-port: command FDCST EQU 14 ;fdc-port: status DMAL EQU 15 ;dma-port: dma address low DMAH EQU 16 ;dma-port: dma address high MMUINI EQU 20 ;initialize mmu MMUSEL EQU 21 ;bank select mmu TIMER EQU 27 ;interrupt timer ; POLL EQU 131 ;xdos poll function PLCI0 EQU 0 ;poll console in #0 FLAGSET EQU 133 ;xdos flag set function ; ; jump vector for individual subroutines ; JP COMMONBASE ;commonbase JP WARMSTART ;warm start JP CONST ;console status JP CONIN ;console character in JP CONOUT ;console character out JP LIST ;list character out JP PUNCH ;not used by MP/M 2 JP READER ;not used by MP/M 2 JP HOME ;move head to home JP SELDSK ;select disk JP SETTRK ;set track numer JP SETSEC ;set sector number JP SETDMA ;set dma address JP READ ;read disk JP WRITE ;write disk JP LISTST ;not used by MP/M 2 JP SECTRAN ;sector translate JP SELMEMORY ;select memory JP POLLDEVICE ;poll device JP STARTCLOCK ;start clock JP STOPCLOCK ;stop clock JP EXITREGION ;exit region JP MAXCONSOLE ;maximum console number JP SYSTEMINIT ;system initialization JP IDLE ;idle prozedure ; COMMONBASE: JP COLDSTART SWTUSER: JP $-$ SWTSYS: JP $-$ PDISP: JP $-$ XDOS: JP $-$ SYSDAT: DEFW $-$ ; COLDSTART: WARMSTART: LD C,0 JP XDOS ;system reset, terminate prozess ; ; MP/M II V2.0 Console Bios ; CONST: CALL PTBLJMP ;compute and jump to handler DW PTSTI0 ; CONIN: CALL PTBLJMP ;compute and jump to handle DW PTIN0 ; CONOUT: CALL PTBLJMP ;compute and jump to handler DW PTOUT0 ; PTSTI0: IN A,(CONSTA) ;console 0 input RET ; PTIN0: LD C,POLL ;poll console 0 status in LD E,PLCI0 CALL XDOS ;poll console 0 IN A,(CONDAT) ;read character AND 7FH ;strip parity RET ; PTOUT0: LD A,C ;console 0 output OUT (CONDAT),A RET ; PTBLJMP: ;compute and jump to handler LD A,D ADD A,A ;double table index for adress offset POP HL ;return adress of jump table LD E,A LD D,0 ADD HL,DE ;table index * 2 + table base LD E,(HL) ;get handler address INC HL LD D,(HL) EX DE,HL JP (HL) ;jump to computed handler ; LIST: LD A,C OUT (PRTDAT),A RET ; ; not used by MP/M 2 PUNCH: READER: LISTST: RET ; ; MP/M II V2.0 Xios ; ; select/protect memory ; BC = address of memory descriptor SELMEMORY: LD HL,3 ;offset memory bank in memory descriptor ADD HL,BC LD A,(HL) ;get bank OUT (MMUSEL),A ;and select it RET ; ; poll character devices ; POLLDEVICE: JP PTSTI0 ;poll console 0 status in ; ; start clock ; STARTCLOCK: LD A,0FFH LD (TICKN),A RET ; ; stop clock ; STOPCLOCK: XOR A LD (TICKN),A RET ; ; exit region: ; enable interrupt if not preempted or in dispatcher ; EXITREGION: LD A,(PREEMP) OR A RET NZ EI RET ; ; maximum console number ; MAXCONSOLE: LD A,1 RET ; ; system initialization ; C MP/M debugger restart # ; DE MP/M entry point for debugger ; HL BIOS jump table address ; SYSTEMINIT: ; LD A,8 ;initialize banked memory OUT (MMUINI),A LD B,A ; SYS1: DEC B LD A,B OUT (MMUSEL),A ;select every bank and initialize LD A,0C3H ;jp instruction LD (0),A LD (38H),A LD (1),HL PUSH HL LD HL,INTHND LD (39H),HL POP HL JP NZ,SYS1 ; LD HL,SIGNON ;print message SYS2: LD A,(HL) OR A JP Z,SYS3 OUT (CONDAT),A INC HL JP SYS2 ; SYS3: IM 1 LD A,1 ;enable 20ms interrupt timer OUT (TIMER),A EI RET ; ; idle ; IDLE: EI HALT RET ; ; interrupt handler ; INTHND: LD (SVDHL),HL ;save registers POP HL LD (SVDRET),HL PUSH AF LD HL,0 ADD HL,SP LD (SVDSP),HL LD SP,INTSTK PUSH DE PUSH BC LD A,0FFH ;set preempted flag LD (PREEMP),A LD A,(TICKN) OR A ;test tick, indicates delayed process JP Z,INTHND1 LD C,FLAGSET ;set flag #1 each tick LD E,1 CALL XDOS INTHND1: LD HL,CNT50 ;decrement tick counter DEC (HL) JP NZ,INTDONE LD (HL),50 ;set flag #2 each second LD C,FLAGSET LD E,2 CALL XDOS INTDONE: XOR A ;clear preempted flag LD (PREEMP),A POP BC ;restore registers POP DE LD HL,(SVDSP) LD SP,HL POP AF LD HL,(SVDRET) PUSH HL LD HL,(PDISP+1) ;dispatch processes PUSH HL LD HL,(SVDHL) RETI ; ; i/o drivers for disks ; ; move to the track 00 position of current drive ; translate this call into a settrk call with parameter 00 ; HOME: LD C,0 ;select track 0 JP SETTRK ;we will move to 00 on first read/write ; ; select disk given by register C ; SELDSK: LD HL,0000H ;error return code LD A,C CP 4 ;must be between 0 and 3 JR NC,SELHD ;no carry if 4,5,... ; disk number is in the proper range ; compute proper disk parameter header address OUT (FDCD),A ;selekt disk drive LD L,A ;L=disk number 0,1,2,3 ADD HL,HL ;*2 ADD HL,HL ;*4 ADD HL,HL ;*8 ADD HL,HL ;*16 (size of each header) LD DE,DPBASE ADD HL,DE ;HL=.dpbase(diskno*16) RET SELHD: CP 8 ;select the harddisk? RET NZ ;no, error OUT (FDCD),A ;select disk drive LD HL,HDBASE ;HL=hdbase for harddisk RET ; ; set track given by register c ; SETTRK: LD A,C OUT (FDCT),A RET ; ; set sector given by register c ; SETSEC: LD A,C OUT (FDCS),A RET ; ; translate the sector given by BC using the ; translate table given by DE ; SECTRAN: EX DE,HL ;HL=.trans ADD HL,BC ;HL=.trans(sector) LD L,(HL) ;L = trans(sector) LD H,0 ;HL= trans(sector) RET ;with value in HL ; ; set dma address given by registers b and c ; SETDMA: LD A,C ;low order address OUT (DMAL),A LD A,B ;high order address OUT (DMAH),A ;in dma RET ; ; perform read operation ; READ: XOR A ;read command -> A JP WAITIO ;to perform the actual i/o ; ; perform a write operation ; WRITE: LD A,1 ;write command -> A ; ; enter here from read and write to perform the actual i/o ; operation. return a 00h in register a if the operation completes ; properly, and 01h if an error occurs during the read or write ; ; in this case, we have saved the disk number in 'diskno' (0-3) ; the track number in 'track' (0-76) ; the sector number in 'sector' (1-26) ; the dma address in 'dmaad' (0-65535) ; WAITIO: PUSH AF CALL SWTUSER ;switch to user page POP AF OUT (FDCOP),A ;start i/o operation IN A,(FDCST) ;status of i/o operation -> A PUSH AF CALL SWTSYS ;switch back to system page POP AF RET ; ; XIOS data segment ; SIGNON: DEFB 13,10 DEFM 'MP/M 2 XIOS V1.2 for Z80SIM, ' DEFM 'Copyright 1989-2006 by Udo Munk' DEFB 13,10,0 ; TICKN: DEFB 0 ;flag for tick PREEMP: DEFB 0 ;preempted flag TOD: DEFS 4 ;time of day SVDHL: DEFS 2 ;save hl during interrupt SVDRET: DEFS 2 ;save return address during interrupt SVDSP: DEFS 2 ;save sp during interrupt CNT50: DEFB 50 ;50 ticks a 20ms = 1 second ;interrupt stack DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H INTSTK: ; ; fixed data tables for four-drive standard ; IBM-compatible 8" disks ; ; disk parameter header for disk 00 DPBASE: DEFW TRANS,0000H DEFW 0000H,0000H DEFW DIRBF,DPBLK DEFW CHK00,ALL00 ; disk parameter header for disk 01 DEFW TRANS,0000H DEFW 0000H,0000H DEFW DIRBF,DPBLK DEFW CHK01,ALL01 ; disk parameter header for disk 02 DEFW TRANS,0000H DEFW 0000H,0000H DEFW DIRBF,DPBLK DEFW CHK02,ALL02 ; disk parameter header for disk 03 DEFW TRANS,0000H DEFW 0000H,0000H DEFW DIRBF,DPBLK DEFW CHK03,ALL03 ; ; sector translate vector for the IBM 8" disks ; TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 DEFB 25,5,11,17 ;sectors 5,6,7,8 DEFB 23,3,9,15 ;sectors 9,10,11,12 DEFB 21,2,8,14 ;sectors 13,14,15,16 DEFB 20,26,6,12 ;sectors 17,18,19,20 DEFB 18,24,4,10 ;sectors 21,22,23,24 DEFB 16,22 ;sectors 25,26 ; ; disk parameter block, common to all IBM 8" disks ; DPBLK: DEFW 26 ;sectors per track DEFB 3 ;block shift factor DEFB 7 ;block mask DEFB 0 ;extent mask DEFW 242 ;disk size-1 DEFW 63 ;directory max DEFB 192 ;alloc 0 DEFB 0 ;alloc 1 DEFW 16 ;check size DEFW 2 ;track offset ; ; fixed data tables for 4MB harddisk ; ; disk parameter header HDBASE: DEFW HDTRA,0000H DEFW 0000H,0000H DEFW DIRBF,HDBLK DEFW CHKHD,ALLHD ; ; sector translate vector for the hardisk ; HDTRA: DEFB 1,2,3,4,5,6,7,8,9,10 DEFB 11,12,13,14,15,16,17,18,19,20 DEFB 21,22,23,24,25,26,27,28,29,30 DEFB 31,32,33,34,35,36,37,38,39,40 DEFB 41,42,43,44,45,46,47,48,49,50 DEFB 51,52,53,54,55,56,57,58,59,60 DEFB 61,62,63,64,65,66,67,68,69,70 DEFB 71,72,73,74,75,76,77,78,79,80 DEFB 81,82,83,84,85,86,87,88,89,90 DEFB 91,92,93,94,95,96,97,98,99,100 DEFB 101,102,103,104,105,106,107,108,109,110 DEFB 111,112,113,114,115,116,117,118,119,120 DEFB 121,122,123,124,125,126,127,128 ; ; disk parameter block for harddisk ; HDBLK: DEFW 128 ;sectors per track DEFB 4 ;block shift factor DEFB 15 ;block mask DEFB 0 ;extent mask DEFW 2039 ;disk size-1 DEFW 1023 ;directory max DEFB 255 ;alloc 0 DEFB 255 ;alloc 1 DEFW 0 ;check size DEFW 0 ;track offset ; DIRBF: DEFS 128 ;scratch directory area ALL00: DEFS 31 ;allocation vector 0 ALL01: DEFS 31 ;allocation vector 1 ALL02: DEFS 31 ;allocation vector 2 ALL03: DEFS 31 ;allocation vector 3 ALLHD: DEFS 255 ;allocation vector harddisk CHK00: DEFS 16 ;check vector 0 CHK01: DEFS 16 ;check vector 1 CHK02: DEFS 16 ;check vector 2 CHK03: DEFS 16 ;check vector 3 CHKHD: DEFS 0 ;check vector harddisk ; END