diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 8ece0606..197a75ef 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -2,8 +2,10 @@ Version 2.9.0 ------------- - WBW: Implemented multi-sector I/O in all disk drivers - WBW: Added support for RC2014 SMB Floppy controller modules (SMC and WDC) -- WBW: New function dispatching for disk drivers +- WBW: New function dispatching for character/disk/video drivers - WBW: Updated FDU app to support RC2014 floppy controllers +- WBW: Added TIMER app to display system timer value +- WBW: Refactored interrupt management code Version 2.8.6 ------------- diff --git a/ReadMe.txt b/ReadMe.txt index e15b86cf..3d935c72 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -7,7 +7,7 @@ *********************************************************************** Wayne Warthen (wwarthen@gmail.com) -Version 2.9.0, 2018-01-08 +Version 2.9.0 (prerelease), 2018-01-16 https://www.retrobrewcomputers.org/ RomWBW is a ROM-based implementation of CP/M-80 2.2 and Z-System for diff --git a/Source/Apps/Assign.asm b/Source/Apps/Assign.asm index dae8fc47..adb53a13 100644 --- a/Source/Apps/Assign.asm +++ b/Source/Apps/Assign.asm @@ -39,7 +39,7 @@ bdos .equ $0005 ; BDOS invocation vector stamp .equ $40 ; loc of RomWBW CBIOS zero page stamp ; rmj .equ 2 ; CBIOS version - major -rmn .equ 8 ; CBIOS version - minor +rmn .equ 9 ; CBIOS version - minor ; ;=============================================================================== ; Code Section diff --git a/Source/Apps/Build.cmd b/Source/Apps/Build.cmd index c308521a..fd2ad1ce 100644 --- a/Source/Apps/Build.cmd +++ b/Source/Apps/Build.cmd @@ -18,6 +18,7 @@ call :asm Talk || goto :eof call :asm OSLdr || goto :eof call :asm Mode || goto :eof call :asm RTC || goto :eof +call :asm Timer || goto :eof zx Z80ASM -SYSGEN/F diff --git a/Source/Apps/Format.asm b/Source/Apps/Format.asm index f7b78e2b..ecb048c4 100644 --- a/Source/Apps/Format.asm +++ b/Source/Apps/Format.asm @@ -31,7 +31,7 @@ bdos .equ $0005 ; BDOS invocation vector ;stamp .equ $40 ; loc of RomWBW CBIOS zero page stamp ; rmj .equ 2 ; CBIOS version - major -rmn .equ 8 ; CBIOS version - minor +rmn .equ 9 ; CBIOS version - minor ; ;=============================================================================== ; Code Section diff --git a/Source/Apps/Mode.asm b/Source/Apps/Mode.asm index c9fa6383..604b0511 100644 --- a/Source/Apps/Mode.asm +++ b/Source/Apps/Mode.asm @@ -48,7 +48,7 @@ bdos .equ $0005 ; BDOS invocation vector ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr ; rmj .equ 2 ; intended CBIOS version - major -rmn .equ 8 ; intended CBIOS version - minor +rmn .equ 9 ; intended CBIOS version - minor ; bf_cioinit .equ $04 ; HBIOS: CIOINIT function bf_cioquery .equ $05 ; HBIOS: CIOQUERY function diff --git a/Source/Apps/OSLdr.asm b/Source/Apps/OSLdr.asm index 98ea8070..4ca2973f 100644 --- a/Source/Apps/OSLdr.asm +++ b/Source/Apps/OSLdr.asm @@ -115,7 +115,7 @@ hbxcpy .equ $FFF6 ; Bank copy function entry address ; relocate ourselves to upper memory ld hl,$0000 ; from startup location ld de,runloc ; to running location - ld bc,$1000 ; assume we are no more that $3000 bytes + ld bc,$0800 ; assume we are no more that 2048 bytes ldir ; copy ourselves jp phase2 ; jump to new location @@ -991,7 +991,7 @@ bufptr .dw 0 ; active pointer into buffer ; ; Messages ; -msgban .db "OSLDR v1.0 for RomWBW, 08-Oct-2014",0 +msgban .db "OSLDR v1.1 for RomWBW, 16-Jan-2018",0 msghb .db " (HBIOS Mode)",0 msgub .db " (UBIOS Mode)",0 msguse .db "Usage: OSLDR [/F] []\r\n" diff --git a/Source/Apps/Startup.asm b/Source/Apps/Startup.asm index 6e283f30..2e902fa6 100644 --- a/Source/Apps/Startup.asm +++ b/Source/Apps/Startup.asm @@ -34,7 +34,7 @@ bdos .equ $0005 ; BDOS invocation vector ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr ; rmj .equ 2 ; intended CBIOS version - major -rmn .equ 8 ; intended CBIOS version - minor +rmn .equ 9 ; intended CBIOS version - minor ; bf_cioinit .equ $04 ; HBIOS: CIOINIT function bf_cioquery .equ $05 ; HBIOS: CIOQUERY function diff --git a/Source/Apps/Timer.asm b/Source/Apps/Timer.asm new file mode 100644 index 00000000..8d925216 --- /dev/null +++ b/Source/Apps/Timer.asm @@ -0,0 +1,411 @@ +;=============================================================================== +; SIMER - Display system timer value +; +;=============================================================================== +; +; Author: Wayne Warthen (wwarthen@gmail.com) +;_______________________________________________________________________________ +; +; Usage: +; TIMER [/C] [/?] +; ex: TIMER (display current timer value) +; TIMER /? (display version and usage) +; TIMER /C (display timer value continuously) +; +; Operation: +; Reads and displays system timer value. +;_______________________________________________________________________________ +; +; Change Log: +; 2018-01-14 [WBW] Initial release +;_______________________________________________________________________________ +; +; ToDo: +;_______________________________________________________________________________ +; +;=============================================================================== +; Definitions +;=============================================================================== +; +stksiz .equ $40 ; Working stack size +; +restart .equ $0000 ; CP/M restart vector +bdos .equ $0005 ; BDOS invocation vector +; +ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr +; +rmj .equ 2 ; intended CBIOS version - major +rmn .equ 9 ; intended CBIOS version - minor +; +bf_sysget .equ $F8 ; HBIOS: SYSGET function +bf_sysgettimer .equ $D0 ; TIMER subfunction +; +;=============================================================================== +; Code Section +;=============================================================================== +; + .org $100 +; + ; setup stack (save old value) + ld (stksav),sp ; save stack + ld sp,stack ; set new stack +; + ; initialization + call init ; initialize + jr nz,exit ; abort if init fails +; + ; process + call process ; do main processing + jr nz,exit ; abort on error +; +exit: ; clean up and return to command processor + call crlf ; formatting + ld sp,(stksav) ; restore stack + ;jp restart ; return to CP/M via restart + ret ; return to CP/M w/o restart +; +; Initialization +; +init: + call crlf ; formatting + ld de,msgban ; point to version message part 1 + call prtstr ; print it +; +initx + ; initialization complete + xor a ; signal success + ret ; return +; +; Process +; +process: + ; look for start of parms + ld hl,$81 ; point to start of parm area (past len byte) + call nonblank ; skip to next non-blank char + jp z,process0 ; no parms, go to display +; + ; check for special option, introduced by a "/" + cp '/' ; start of options? + jp nz,usage ; yes, handle option + call option ; do option processing + ret nz ; done if non-zero reture +; +process0: + call crlf2 ; formatting +; +process1: + ld b,bf_sysget ; HBIOS SYSGET function + ld c,bf_sysgettimer ; TIMER subfunction + rst 08 ; call HBIOS, DE:HL := timer value + + ld a,(first) + or a + ld a,0 + ld (first),a + jr nz,process1a + + ; test for new value + ld a,(last) ; last LSB value to A + cp l ; compare to current LSB + jr z,process2 ; if equal, bypass display + +process1a: + ; save and print new value + ld a,l ; new LSB value to A + ld (last),a ; save as last value + call prtcr ; back to start of line + call nz,prthex32 ; display it +; +process2: + ld a,(cont) ; continuous display? + or a ; test for true/false + jr z,process3 ; if false, get out +; + ld c,6 ; BDOS: direct console I/O + ld e,$FF ; input char + call bdos ; call BDOS, A := char + or a ; test for zero + jr z,process1 ; loop until char pressed +; +process3: + xor a ; signal success + ret +; +; Handle special options +; +option: +; + inc hl ; next char + ld a,(hl) ; get it + cp '?' ; is it a '?'? + jp z,usage ; yes, display usage + cp 'C' ; is it a 'C', continuous? + jp z,setcont ; yes, set continuous display + jp errprm ; anything else is an error +; +usage: +; + call crlf2 ; blank line + ld de,msguse ; point to usage message + call prtstr ; print it + or $FF ; signal no action performed + ret ; and return +; +setcont: +; + or $FF ; set A to true + ld (cont),a ; and save it + xor a ; signal success + ret ; and done +; +; Print character in A without destroying any registers +; +prtchr: + push bc ; save registers + push de + push hl + ld e,a ; character to print in E + ld c,$02 ; BDOS function to output a character + call bdos ; do it + pop hl ; restore registers + pop de + pop bc + ret +; +prtdot: +; + ; shortcut to print a dot preserving all regs + push af ; save af + ld a,'.' ; load dot char + call prtchr ; print it + pop af ; restore af + ret ; done +; +prtcr: +; + ; shortcut to print a dot preserving all regs + push af ; save af + ld a,13 ; load CR value + call prtchr ; print it + pop af ; restore af + ret ; done +; +; Print a zero terminated string at (DE) without destroying any registers +; +prtstr: + push de +; +prtstr1: + ld a,(de) ; get next char + or a + jr z,prtstr2 + call prtchr + inc de + jr prtstr1 +; +prtstr2: + pop de ; restore registers + ret +; +; Print the value in A in hex without destroying any registers +; +prthex: + push af ; save AF + push de ; save DE + call hexascii ; convert value in A to hex chars in DE + ld a,d ; get the high order hex char + call prtchr ; print it + ld a,e ; get the low order hex char + call prtchr ; print it + pop de ; restore DE + pop af ; restore AF + ret ; done +; +; print the hex word value in bc +; +prthexword: + push af + ld a,b + call prthex + ld a,c + call prthex + pop af + ret +; +; print the hex dword value in de:hl +; +prthex32: + push bc + push de + pop bc + call prthexword + push hl + pop bc + call prthexword + pop bc + ret +; +; Convert binary value in A to ascii hex characters in DE +; +hexascii: + ld d,a ; save A in D + call hexconv ; convert low nibble of A to hex + ld e,a ; save it in E + ld a,d ; get original value back + rlca ; rotate high order nibble to low bits + rlca + rlca + rlca + call hexconv ; convert nibble + ld d,a ; save it in D + ret ; done +; +; Convert low nibble of A to ascii hex +; +hexconv: + and $0F ; low nibble only + add a,$90 + daa + adc a,$40 + daa + ret +; +; Print value of A or HL in decimal with leading zero suppression +; Use prtdecb for A or prtdecw for HL +; +prtdecb: + push hl + ld h,0 + ld l,a + call prtdecw ; print it + pop hl + ret +; +prtdecw: + push af + push bc + push de + push hl + call prtdec0 + pop hl + pop de + pop bc + pop af + ret +; +prtdec0: + ld e,'0' + ld bc,-10000 + call prtdec1 + ld bc,-1000 + call prtdec1 + ld bc,-100 + call prtdec1 + ld c,-10 + call prtdec1 + ld e,0 + ld c,-1 +prtdec1: + ld a,'0' - 1 +prtdec2: + inc a + add hl,bc + jr c,prtdec2 + sbc hl,bc + cp e + ret z + ld e,0 + call prtchr + ret +; +; Start a new line +; +crlf2: + call crlf ; two of them +crlf: + push af ; preserve AF + ld a,13 ; + call prtchr ; print it + ld a,10 ; + call prtchr ; print it + pop af ; restore AF + ret +; +; Get the next non-blank character from (HL). +; +nonblank: + ld a,(hl) ; load next character + or a ; string ends with a null + ret z ; if null, return pointing to null + cp ' ' ; check for blank + ret nz ; return if not blank + inc hl ; if blank, increment character pointer + jr nonblank ; and loop +; +; Convert character in A to uppercase +; +ucase: + cp 'a' ; if below 'a' + ret c ; ... do nothing and return + cp 'z' + 1 ; if above 'z' + ret nc ; ... do nothing and return + res 5,a ; clear bit 5 to make lower case -> upper case + ret ; and return +; +; Add the value in A to HL (HL := HL + A) +; +addhl: + add a,l ; A := A + L + ld l,a ; Put result back in L + ret nc ; if no carry, we are done + inc h ; if carry, increment H + ret ; and return +; +; Jump indirect to address in HL +; +jphl: + jp (hl) +; +; Errors +; +erruse: ; command usage error (syntax) + ld de,msguse + jr err +; +errprm: ; command parameter error (syntax) + ld de,msgprm + jr err +err: ; print error string and return error signal + call crlf ; print newline +; +err1: ; without the leading crlf + call prtstr ; print error string +; +err2: ; without the string +; call crlf ; print newline + or $FF ; signal error + ret ; done +; +;=============================================================================== +; Storage Section +;=============================================================================== +; +last .db 0 ; last LSB of timer value +cont .db 0 ; non-zero indicates continuous display +first .db $FF ; first pass flag (true at start) +; +stksav .dw 0 ; stack pointer saved at start + .fill stksiz,0 ; stack +stack .equ $ ; stack top +; +; Messages +; +msgban .db "TIMER v1.0, 14-Jan-2018",13,10 + .db "Copyright (C) 2018, Wayne Warthen, GNU GPL v3",0 +msguse .db "Usage: TIMER [/C] [/?]",13,10 + .db " ex. TIMER (display current timer value)",13,10 + .db " TIMER /? (display version and usage)",13,10 + .db " TIMER /C (display timer value continuously)",0 +msgprm .db "Parameter error (TIMER /? for usage)",0 +; + .end diff --git a/Source/Build.cmd b/Source/Build.cmd index 2493a5a0..28b4c1a5 100644 --- a/Source/Build.cmd +++ b/Source/Build.cmd @@ -5,5 +5,5 @@ REM setlocal & call BuildDoc || exit /b 1 & endlocal setlocal & call BuildHardware || exit /b 1 & endlocal setlocal & call BuildImages || exit /b 1 & endlocal setlocal & call BuildShared || exit /b 1 & endlocal -setlocal & call BuildBP || exit /b 1 & endlocal +REM setlocal & call BuildBP || exit /b 1 & endlocal setlocal & call BuildROM %* || exit /b 1 & endlocal \ No newline at end of file diff --git a/Source/HBIOS/API.txt b/Source/HBIOS/API.txt index f329d1b6..5463890d 100644 --- a/Source/HBIOS/API.txt +++ b/Source/HBIOS/API.txt @@ -52,6 +52,10 @@ GET ($F8): VDACNT ($40): BC=Function/Subfunction A=Result E=Video Unit Count + + TIMER ($D0): + BC=Function/Subfunction A=Result + DE:HL=Timer Value (32 bit) BOOTINFO ($E0): BC=Function/Subfunction A=Result @@ -77,6 +81,10 @@ GET ($F8): SET ($F9): BC=Function/Subfunction A=Result + TIMER ($D0): + BC=Function/Subfunction A=Result + DE:HL=Timer Value (32 bit) + BOOTINFO ($E0): BC=Function/Subfunction A=Result DE=Boot Volume (Disk Unit/Slice) diff --git a/Source/HBIOS/Config/SBC_simh.asm b/Source/HBIOS/Config/SBC_simh.asm index 06ac2b65..4c31742e 100644 --- a/Source/HBIOS/Config/SBC_simh.asm +++ b/Source/HBIOS/Config/SBC_simh.asm @@ -5,6 +5,9 @@ ; #include "cfg_sbc.asm" ; +INTMODE .SET 1 ; INT MODE 1 +HTIMENABLE .SET TRUE ; SIMH TIMER +; DSRTCENABLE .SET FALSE ; DS-1302 CLOCK DRIVER SIMRTCENABLE .SET TRUE ; SIMH CLOCK DRIVER ; diff --git a/Source/HBIOS/acia.asm b/Source/HBIOS/acia.asm index 0b6e939c..58d6ec0d 100644 --- a/Source/HBIOS/acia.asm +++ b/Source/HBIOS/acia.asm @@ -60,7 +60,7 @@ ACIA_PREINIT0: JR Z,ACIA_PREINIT2 ; SKIP IT IF NOTHING FOUND ; PUSH BC ; SAVE LOOP CONTROL - LD BC,ACIA_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,ACIA_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL NZ,CIO_ADDENT ; ADD ENTRY IF ACIA FOUND, BC:DE POP BC ; RESTORE LOOP CONTROL ; @@ -216,24 +216,9 @@ ACIAB_INT1: OR $FF ; NZ SET TO INDICATE INT HANDLED RET ; AND RETURN ; +; DRIVER FUNCTION TABLE ; -; -ACIA_DISPATCH: - ; DISPATCH TO FUNCTION HANDLER - PUSH HL ; SAVE HL FOR NOW - LD A,B ; GET FUNCTION - AND $0F ; ISOLATE LOW NIBBLE - RLCA ; X 2 FOR WORD OFFSET INTO FUNCTION TABLE - LD HL,ACIA_FTBL ; START OF FUNC TABLE - CALL ADDHLA ; HL := ADDRESS OF ADDRESS OF FUNCTION - LD A,(HL) ; DEREF HL - INC HL ; ... - LD H,(HL) ; ... - LD L,A ; ... TO GET ADDRESS OF FUNCTION - EX (SP),HL ; RESTORE HL & PUT FUNC ADDRESS -> (SP) - RET ; EFFECTIVELY A JP TO TGT ADDRESS - -ACIA_FTBL: +ACIA_FNTBL: .DW ACIA_IN .DW ACIA_OUT .DW ACIA_IST @@ -241,6 +226,9 @@ ACIA_FTBL: .DW ACIA_INITDEV .DW ACIA_QUERY .DW ACIA_DEVICE +#IF (($ - ACIA_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID ACIA FUNCTION TABLE ***\n" +#ENDIF ; ; ; @@ -256,7 +244,7 @@ ACIA_IN: ACIAA_IN: CALL ACIAA_IST ; RECEIVED CHAR READY? JR Z,ACIAA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - DI ; AVOID COLLIACIAN WITH INT HANDLER + HB_DI ; AVOID COLLISION WITH INT HANDLER LD A,(ACIAA_BUFCNT) ; GET COUNT DEC A ; DECREMENT COUNT LD (ACIAA_BUFCNT),A ; SAVE SAVE IT @@ -276,14 +264,14 @@ ACIAA_IN0: LD HL,ACIAA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER ACIAA_IN1: LD (ACIAA_TL),HL ; SAVE UPDATED TAIL POINTER - EI ; INTERRUPTS OK AGAIN + HB_EI ; INTERRUPTS OK AGAIN XOR A ; SIGNAL SUCCESS RET ; AND DONE ; ACIAB_IN: CALL ACIAB_IST ; RECEIVED CHAR READY? JR Z,ACIAB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - DI ; AVOID COLLIACIAN WITH INT HANDLER + HB_DI ; AVOID COLLISION WITH INT HANDLER LD A,(ACIAB_BUFCNT) ; GET COUNT DEC A ; DECREMENT COUNT LD (ACIAB_BUFCNT),A ; SAVE SAVE IT @@ -303,7 +291,7 @@ ACIAB_IN0: LD HL,ACIAB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER ACIAB_IN1: LD (ACIAB_TL),HL ; SAVE UPDATED TAIL POINTER - EI ; INTERRUPTS OK AGAIN + HB_EI ; INTERRUPTS OK AGAIN XOR A ; SIGNAL SUCCESS RET ; AND DONE ; diff --git a/Source/HBIOS/ansi.asm b/Source/HBIOS/ansi.asm index be63fabb..77435b24 100644 --- a/Source/HBIOS/ansi.asm +++ b/Source/HBIOS/ansi.asm @@ -22,7 +22,7 @@ ANSI_DEFCOLOR .EQU 7 ; WHITE ON BLACK ; ON ENTRY: ; DE: DISPATCH ADDRESS OF CALLING VDA DRIVER ; RETURNS: -; DE: OUR CIO DISPATCH ADDRESS +; DE: OUR CIO FUNC TBL ADDRESS ; ANSI_INIT: ; PREVENT ATTEMPTS TO INIT MULTIPLE INSTANCES FOR NOW @@ -35,13 +35,13 @@ ANSI_INIT: LD (ANSI_DEVNUM),A ; SAVE IT LD A,C ; VDA UNIT NUMBER PASSED IN C LD (ANSI_VDAUNIT),A ; SAVE IT - LD (ANSI_VDADISPADR),DE ; RECORD VDA DISPATCH ADDRESS + ;LD (ANSI_VDADISPADR),DE ; RECORD VDA DISPATCH ADDRESS ; ; INIT/RESET OUR INTERNAL STATE CALL ANSI_RESET ; FULL RESET OF EMULATOR INTERNAL STATE RET NZ ; BAIL OUT ON ERROR ; - LD DE,ANSI_DISPATCH ; RETURN OUR DISPATCH ADDRESS + LD DE,ANSI_FNTBL ; RETURN OUR FUNC TBL ADDRESS XOR A ; SIGNAL SUCCESS RET ; RETURN ; @@ -86,28 +86,25 @@ ANSI_RESET1: ; LOOP TO RESET TAB STOPS ; ; ANSI_VDADISP: - JP PANIC -ANSI_VDADISPADR .EQU $ - 2 -; -; -; -ANSI_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,ANSI_CIOIN ; $30 - DEC A - JR Z,ANSI_CIOOUT ; $31 - DEC A - JR Z,ANSI_CIOIST ; $32 - DEC A - JR Z,ANSI_CIOOST ; $33 - DEC A - JR Z,ANSI_CIOINIT ; $34 - DEC A - JP Z,ANSI_CIOQUERY ; $35 - DEC A - JP Z,ANSI_CIODEVICE ; $36 - CALL PANIC +; JP PANIC +;ANSI_VDADISPADR .EQU $ - 2 + LD A,(ANSI_VDAUNIT) + LD C,A + JP VDA_DISPATCH +; +; FUNCTION TABLE +; +ANSI_FNTBL: + .DW ANSI_IN + .DW ANSI_OUT + .DW ANSI_IST + .DW ANSI_OST + .DW ANSI_INITDEV + .DW ANSI_QUERY + .DW ANSI_DEVICE +#IF (($ - ANSI_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID ANSI FUNCTION TABLE ***\n" +#ENDIF ; ;================================================================================================== ; ANSI EMULATION MODULE BIOS FUNCTION ENTRY POINTS @@ -115,12 +112,12 @@ ANSI_DISPATCH: ; ; READ A CHARACTER ; -ANSI_CIOIN: ; HANDLE INPUT REQUEST +ANSI_IN: ; HANDLE INPUT REQUEST ; ; RETURN QUEUED DATA IF WE HAVE ANY LD A,(ANSI_QLEN) ; GET THE CURRENT QUEUE LENGTH OR A ; SET FLAGS - JR Z,ANSI_CIOIN1 ; NOTHING THERE, GO TO KEYBOARD READ + JR Z,ANSI_IN1 ; NOTHING THERE, GO TO KEYBOARD READ DEC A ; DECREMENT THE QUEUE LENGTH LD (ANSI_QLEN),A ; AND SAVE IT LD HL,(ANSI_QPTR) ; GET THE QUEUE POINTER @@ -131,44 +128,44 @@ ANSI_CIOIN: ; HANDLE INPUT REQUEST XOR A ; SIGNAL SUCCESS RET ; DONE ; -ANSI_CIOIN1: ; PERFORM ACTUAL KEYBOARD INPUT +ANSI_IN1: ; PERFORM ACTUAL KEYBOARD INPUT LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ CALL ANSI_VDADISP ; CALL VDA DISPATCHER LD A,E ; CHARACTER READ INTO A BIT 7,A ; TEST HIGH BIT - JR NZ,ANSI_CIOIN2 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR + JR NZ,ANSI_IN2 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR XOR A ; OTHERWISE, SIGNAL SUCCESS RET ; AND RETURN THE KEY ; -ANSI_CIOIN2: ; HANDLE SPECIAL KEY +ANSI_IN2: ; HANDLE SPECIAL KEY CALL ANSI_KDISP ; IF $80 OR HIGHER, DISPATCH - JR ANSI_CIOIN ; AND LOOP + JR ANSI_IN ; AND LOOP ; ; WRITE A CHARACTER W/ EMULATION ; -ANSI_CIOOUT: - LD HL,ANSI_CIOOUT2 ; RETURN ADDRESS +ANSI_OUT: + LD HL,ANSI_OUT2 ; RETURN ADDRESS PUSH HL ; PUT IT ON STACK LD A,E ; GET THE INCOMING CHARACTER CP $20 ; $00-$1F IS C0 JP C,ANSI_C0DISP ; IF C0, DO C0 DISPATCH CP $80 ; $20-$7F - JR C,ANSI_CIOOUT1 ; HANDLE VIA STATE MACHINE + JR C,ANSI_OUT1 ; HANDLE VIA STATE MACHINE CP $A0 ; $80-$9F IS C1 JP C,ANSI_C1DISP ; IF C1, DO C1 DISPATCH ; -ANSI_CIOOUT1: ; PROCESS OTHER CHARS VIA STATE MACHINE +ANSI_OUT1: ; PROCESS OTHER CHARS VIA STATE MACHINE LD HL,(ANSI_STATE) ; LOAD THE CURRENT STATE JP (HL) ; DO IT ; CALL JPHL ; DO IT ; -ANSI_CIOOUT2: ; SET RESULT AND RETURN +ANSI_OUT2: ; SET RESULT AND RETURN XOR A ; SIGNAL SUCCESS RET ; ; CHECK INPUT STATUS ; -ANSI_CIOIST: ; CHECK QUEUE FIRST +ANSI_IST: ; CHECK QUEUE FIRST LD A,(ANSI_QLEN) ; GET CURRENT QUEUE LENGTH OR A ; SET FLAGS RET NZ ; RETURN IF CHAR(S) WAITING @@ -184,7 +181,7 @@ ANSI_CIOIST: ; CHECK QUEUE FIRST CALL ANSI_VDADISP ; DO IT LD A,E ; CHARACTER READ TO A BIT 7,A ; TEST HIGH BIT - JR NZ,ANSI_CIOIST1 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR + JR NZ,ANSI_IST1 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR ; ; REGULAR CHARACTER RECEIVED, QUEUE IT AND RETURN CHARS WAITING STATUS LD HL,ANSI_QUEUE ; SET HL TO START OF QUEUE @@ -194,22 +191,22 @@ ANSI_CIOIST: ; CHECK QUEUE FIRST XOR A ; ZERO ACCUM INC A ; ASSUM := 1 (NUM CHARS IN QUEUE) LD (ANSI_QLEN),A ; SAVE NEW QUEUE LEN - JR ANSI_CIOIST ; REPEAT + JR ANSI_IST ; REPEAT ; -ANSI_CIOIST1: ; HANDLE SPECIAL KEY +ANSI_IST1: ; HANDLE SPECIAL KEY CALL ANSI_KDISP ; DO SPECIAL KEY HANDLING - JR ANSI_CIOIST ; REPEAT + JR ANSI_IST ; REPEAT ; ; CHECK OUTPUT STATUS ; -ANSI_CIOOST: ; VIDEO OUTPUT IS *ALWAYS* READY +ANSI_OST: ; VIDEO OUTPUT IS *ALWAYS* READY XOR A ; ZERO ACCUM INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY RET ; ; INITIALIZE ; -ANSI_CIOINIT: +ANSI_INITDEV: ; RESET THE ATTACHED VDA DEVICE LD B,BF_VDAINI ; FUNC: INIT LD E,-1 ; DO NOT CHANGE VIDEO MODE @@ -220,7 +217,7 @@ ANSI_CIOINIT: ; ; QUERY STATUS ; -ANSI_CIOQUERY: +ANSI_QUERY: LD DE,$FFFF LD HL,$FFFF XOR A @@ -228,7 +225,7 @@ ANSI_CIOQUERY: ; ; REPORT DEVICE ; -ANSI_CIODEVICE: +ANSI_DEVICE: LD D,CIODEV_TERM ; TYPE IS TERMINAL LD A,(ANSI_DEVNUM) ; GET DEVICE NUMBER LD E,A ; PUT IT IN E diff --git a/Source/HBIOS/asci.asm b/Source/HBIOS/asci.asm index 2524f288..d3ef04c7 100644 --- a/Source/HBIOS/asci.asm +++ b/Source/HBIOS/asci.asm @@ -68,21 +68,31 @@ ASCI_PREINIT: ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180 - LD C,0 ; PHYSICAL UNIT INDEX -ASCI_PREINIT1: - PUSH BC ; SAVE LOOP CONTROL - LD D,C ; PHYSICAL UNIT +; LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180 +; LD C,0 ; PHYSICAL UNIT INDEX +;ASCI_PREINIT1: +; PUSH BC ; SAVE LOOP CONTROL +; LD D,C ; PHYSICAL UNIT +; LD E,CIODEV_ASCI ; DEVICE TYPE +; LD BC,ASCI_FNTBL ; BC := FUNCTION TABLE ADDRESS +; CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED +; POP BC ; RESTORE LOOP CONTROL +; INC C ; NEXT PHYSICAL UNIT +; DJNZ ASCI_PREINIT1 ; LOOP UNTIL DONE +; + ; ASCI0 CHANNEL + LD D,0 ; DEVICE ID LD E,CIODEV_ASCI ; DEVICE TYPE - LD BC,ASCI_DISPATCH ; BC := DISPATCH ADDRESS - CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED - POP BC ; RESTORE LOOP CONTROL - INC C ; NEXT PHYSICAL UNIT - DJNZ ASCI_PREINIT1 ; LOOP UNTIL DONE -; + LD BC,ASCI0_FNTBL ; ASCI0 FUNCTION TABLE PTR + CALL CIO_ADDENT LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG CALL ASCI0_INITDEV ; INIT DEVICE -; +; + ; ASCI1 CHANNEL + LD D,1 ; DEVICE ID + LD E,CIODEV_ASCI ; DEVICE TYPE + LD BC,ASCI1_FNTBL ; ASCI1 FUNCTION TABLE PTR + CALL CIO_ADDENT LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG CALL ASCI1_INITDEV ; INIT DEVICE ; @@ -124,36 +134,19 @@ ASCI_INIT: XOR A RET ; -; DISPATCH TO SPECIFIC ASCI UNIT +; DRIVER ASCI0 FUNCTION TABLE ; -ASCI_DISPATCH: - PUSH IY ; PUSH UNIT DATA WORD - POP AF ; POP TO AF, A := DEVICE NUM - OR A ; SET FLAGS - JP Z,ASCI0 - DEC A - JP Z,ASCI1 - CALL PANIC -; -; ASCI 0 FUNCTIONS -; -ASCI0: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,ASCI0_IN - DEC A - JP Z,ASCI0_OUT - DEC A - JP Z,ASCI0_IST - DEC A - JP Z,ASCI0_OST - DEC A - JP Z,ASCI0_INITDEV - DEC A - JP Z,ASCI0_QUERY - DEC A - JP Z,ASCI0_DEVICE - CALL PANIC +ASCI0_FNTBL: + .DW ASCI0_IN + .DW ASCI0_OUT + .DW ASCI0_IST + .DW ASCI0_OST + .DW ASCI0_INITDEV + .DW ASCI0_QUERY + .DW ASCI0_DEVICE +#IF (($ - ASCI0_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID ASCI0 FUNCTION TABLE ***\n" +#ENDIF ; ASCI0_IN: CALL ASCI0_IST @@ -269,8 +262,19 @@ ASCI0_DEVICE: XOR A ; SIGNAL SUCCESS RET ; -; ASCI 1 FUNCTIONS -; +; DRIVER ASCI1 FUNCTION TABLE +; +ASCI1_FNTBL: + .DW ASCI1_IN + .DW ASCI1_OUT + .DW ASCI1_IST + .DW ASCI1_OST + .DW ASCI1_INITDEV + .DW ASCI1_QUERY + .DW ASCI1_DEVICE +#IF (($ - ASCI1_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID ASCI1 FUNCTION TABLE ***\n" +#ENDIF ASCI1: LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 6be5bdf5..5a777cde 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -8,13 +8,14 @@ CPUOSC .EQU 18432000 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTTYPE .EQU IT_Z180 ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) +INTMODE .EQU 2 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) ; DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) ; +HTIMENABLE .EQU FALSE ; TRUE FOR SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 061ceae1..fb9eea28 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -8,13 +8,14 @@ CPUOSC .EQU 18432000 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTTYPE .EQU IT_Z180 ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) +INTMODE .EQU 2 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) ; DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) ; +HTIMENABLE .EQU FALSE ; TRUE FOR SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC diff --git a/Source/HBIOS/cfg_rc.asm b/Source/HBIOS/cfg_rc.asm index a914b4b2..148a3f42 100644 --- a/Source/HBIOS/cfg_rc.asm +++ b/Source/HBIOS/cfg_rc.asm @@ -8,13 +8,14 @@ CPUOSC .EQU 7372800 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTTYPE .EQU IT_RC ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) +INTMODE .EQU 1 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) ; DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) ; +HTIMENABLE .EQU FALSE ; TRUE FOR SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER DSRTCENABLE .EQU FALSE ; DS-1302 CLOCK DRIVER DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 8fd6624a..2e0750fa 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -8,13 +8,14 @@ CPUOSC .EQU 8000000 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTTYPE .EQU IT_NONE ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) +INTMODE .EQU 0 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) ; DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) ; +HTIMENABLE .EQU FALSE ; TRUE FOR SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index 0e9cb1f2..73102395 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -8,13 +8,14 @@ CPUOSC .EQU 20000000 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTTYPE .EQU IT_NONE ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) +INTMODE .EQU 0 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) ; DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) ; +HTIMENABLE .EQU FALSE ; TRUE FOR SIMH TIMER SUPPORT SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index f0bda1ee..753f6755 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -7,6 +7,4 @@ ; #INCLUDE "cfg_zeta.asm" ; USE ZETA CONFIG TO START ; -INTTYPE .SET IT_CTC ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...) -; FDMODE .SET FDMODE_ZETA2 ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 diff --git a/Source/HBIOS/cvdu.asm b/Source/HBIOS/cvdu.asm index bc6eafa7..29277d78 100644 --- a/Source/HBIOS/cvdu.asm +++ b/Source/HBIOS/cvdu.asm @@ -57,13 +57,13 @@ CVDU_INIT1: CALL KBD_INIT ; INITIALIZE KEYBOARD DRIVER ; ADD OURSELVES TO VDA DISPATCH TABLE - LD BC,CVDU_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,CVDU_FNTBL ; BC := FUNCTION TABLE ADDRESS LD DE,CVDU_IDAT ; DE := VGA INSTANCE DATA PTR CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED ; INITIALIZE EMULATION LD C,A ; C := ASSIGNED VIDEO DEVICE NUM - LD DE,CVDU_DISPATCH ; DE := DISPATCH ADDRESS + LD DE,VGA_FNTBL ; DE := FUNCTION TABLE ADDRESS LD HL,CVDU_IDAT ; HL := CVDU INSTANCE DATA PTR CALL TERM_ATTACH ; DO IT @@ -71,43 +71,28 @@ CVDU_INIT1: RET ; ;====================================================================== -; CVDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS +; CVDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== ; -CVDU_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JP Z,CVDU_VDAINI ; $40 - DEC A - JP Z,CVDU_VDAQRY ; $41 - DEC A - JP Z,CVDU_VDARES ; $42 - DEC A - JP Z,CVDU_VDADEV ; $43 - DEC A - JP Z,CVDU_VDASCS ; $44 - DEC A - JP Z,CVDU_VDASCP ; $45 - DEC A - JP Z,CVDU_VDASAT ; $46 - DEC A - JP Z,CVDU_VDASCO ; $47 - DEC A - JP Z,CVDU_VDAWRC ; $48 - DEC A - JP Z,CVDU_VDAFIL ; $49 - DEC A - JP Z,CVDU_VDACPY ; $4A - DEC A - JP Z,CVDU_VDASCR ; $4B - DEC A - JP Z,KBD_STAT ; $4C - DEC A - JP Z,KBD_FLUSH ; $4D - DEC A - JP Z,KBD_READ ; $4E - CALL PANIC +CVDU_FNTBL: + .DW CVDU_VDAINI + .DW CVDU_VDAQRY + .DW CVDU_VDARES + .DW CVDU_VDADEV + .DW CVDU_VDASCS + .DW CVDU_VDASCP + .DW CVDU_VDASAT + .DW CVDU_VDASCO + .DW CVDU_VDAWRC + .DW CVDU_VDAFIL + .DW CVDU_VDACPY + .DW CVDU_VDASCR + .DW KBD_STAT + .DW KBD_FLUSH + .DW KBD_READ +#IF (($ - CVDU_FNTBL) != (VDA_FNCNT * 2)) + .ECHO "*** INVALID CVDU FUNCTION TABLE ***\n" +#ENDIF CVDU_VDAINI: ; RESET VDA diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 5ac6cd98..519b9440 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -67,14 +67,18 @@ MODCNT .SET MODCNT + 1 ; ; ; -#IF (INTTYPE != IT_NONE) -#DEFINE HB_EI EI +#IF (INTMODE == 0) +; NO INTERRUPT HANDLING #DEFINE HB_DI DI -#ELSE #DEFINE HB_EI ; -#DEFINE HB_DI ; +#ELSE +; MODE 1 OR 2 INTERRUPT HANDLING +#DEFINE HB_DI DI +#DEFINE HB_EI EI #ENDIF ; +; +; #IFNDEF APPBOOT ; .ORG 0 @@ -99,7 +103,11 @@ MODCNT .SET MODCNT + 1 .FILL (030H - $),0FFH ; RST 30 RET .FILL (038H - $),0FFH ; RST 38 / IM1 INT - RETI +#IF (INTMODE == 1) + JP INT_IM1 ; JP TO INTERRUPT HANDLER IN HI MEM +#ELSE + RETI ; RETURN W/ INTS DISABLED +#ENDIF .FILL (066H - $),0FFH ; NMI RETN ; @@ -209,11 +217,12 @@ HBX_INVOKE: LD A,BID_BIOS ; HBIOS BANK CALL HBX_BNKSEL ; SELECT IT LD SP,HB_STACK ; NOW USE FULL HBIOS STACK IN HBIOS BANK - + CALL HB_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH PUSH AF ; SAVE AF (FUNCTION RETURN) + LD A,(HB_INVBNK) ; LOAD ORIGINAL BANK CALL HBX_BNKSEL ; SELECT IT POP AF ; RESTORE AF @@ -238,8 +247,27 @@ HBX_BNKSEL: HBX_BNKSEL_INT: ; #IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA)) - OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR + #IF (INTMODE == 1) + ; THIS BIT OF ABSURDITY HANDLES A RARE (BUT FATAL) SITUATION + ; WHERE AN IM1 INTERRUPT OCCURS BETWEEN SETTING THE RAM AND + ; ROM SELECTORS. BRACKETING THE INSTRUCTIONS WITH DI/EI + ; IS CONTRAINDICATED BECAUSE THIS ROUTINE IS CALLED BY + ; OTHER ROUTINES THAT MUST CONTROL INT ENABLE AT A HIGHER + ; LEVEL. THE FOLLOWING TECHNIQUE ENSURES THAT YOU ALWAYS + ; SWITCH DIRECTLY FROM THE PREVIOUS BANK TO THE TARGET BANK + ; WITHOUT AN "ERRANT" BANK BEING ACTIVE BETWEEN THE TWO + ; BANK SELECTION I/O INSTRUCTIONS. THE TECHNIQUE IS ONLY + ; NEEDED WHEN USING INT MODE 1 BECAUSE THAT MODE REQUIRES + ; PAGE ONE TO HAVE A VALID INT HANDLER WHENEVER INTS ARE + ; ENABLED. + ;BIT 7,A ; [8] TEST RAM BIT + ;JR Z,HBX_ROM ; [12/7] IF NOT SET, JUST DO ROM + OR A ; [4] SET FLAGS + JP P,HBX_ROM ; [10] BIT 7 INDICATES RAM + #ENDIF OUT (MPCL_RAM),A ; SET RAM PAGE SELECTOR +HBX_ROM: + OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR RET ; DONE #ENDIF #IF ((PLATFORM == PLT_ZETA2) | (PLATFORM == PLT_RC)) @@ -294,6 +322,7 @@ HBX_BNKSEL1: ; usage of the HL and DE registers is reversed. ; Caller MUST ensure stack is already in high memory. ; Caller MUST preset HBX_SRCBNK and HBX_DSTBNK. +; Caller MUST disable ints if IM1 active ; Enter: ; HL = Source Address ; DE = Destination Address @@ -304,9 +333,9 @@ HBX_BNKSEL1: ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; HBX_BNKCPY: -#IF (INTTYPE == IT_SIMH) - HB_DI -#ENDIF +;#IF (INTMODE < 2) +; DI +;#ENDIF LD (HBX_BC_SP),SP ; PUT STACK LD SP,HBX_TMPSTK ; ... IN HI MEM @@ -338,9 +367,9 @@ HBX_BC_LAST: LD SP,$FFFF ; RESTORE STACK HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE -#IF (INTTYPE == IT_SIMH) - HB_EI -#ENDIF +;#IF (INTMODE == 1) +; EI +;#ENDIF RET ; HBX_BC_ITER: @@ -364,6 +393,8 @@ HBX_BC_ITER: ; ; CALL A ROUTINE IN ANOTHER BANK. ; CALLER MUST ENSURE STACK IS ALREADY IN HIGH MEMORY AND HAS ADEQUATE SPACE. +; IF IM1 INTERRUPTS ARE POSSIBLE, CALLER MUST EITHER DISABLE THEM PRIOR TO +; BNKCALL OR MAKE SURE THAT PAGE ZERO IN TARGTET BANK IS PREPARED FOR THEM. ; ON INPUT A=TARGET BANK, HL=TARGET ADDRESS ; HBX_BNKCALL: @@ -388,11 +419,12 @@ HBX_TGTADR .EQU $ + 1 ; ; PEEK & POKE ROUTINES ; ADDRESS IN HL, BANK IN D, VALUE IN/OUT IN E, A IS TRASHED +; CALLER MUST DISABLE INTS IF IM1 AND ACCESSING PAGE W/O IM1 INT VECTOR ; HBX_PEEK: -#IF (INTTYPE == IT_SIMH) - HB_DI -#ENDIF +;#IF (INTMODE < 2) +; DI +;#ENDIF LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM LD A,(HB_CURBNK) @@ -403,9 +435,9 @@ HBX_PEEK: JR HBX_PPRET ; HBX_POKE: -#IF (INTTYPE == IT_SIMH) - HB_DI -#ENDIF +;#IF (INTMODE < 2) +; DI +;#ENDIF LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM LD A,(HB_CURBNK) @@ -419,12 +451,12 @@ HBX_PPRET: CALL HBX_BNKSEL LD SP,0 ; RESTORE ORIGINAL STACK FRAME HBX_PPSP .EQU $ - 2 -#IF (INTTYPE == IT_SIMH) - HB_EI -#ENDIF +;#IF (INTMODE == 1) +; EI +;#ENDIF RET ; -; SMALL TEMPORARY STACK FOR USE BY HB_INVOKE +; SMALL TEMPORARY STACK FOR USE BY INVOKE, PEEK, AND POKE ; .FILL 20,$CC ; 10 LEVEL STACK HBX_TMPSTK .EQU $ @@ -439,6 +471,8 @@ HBX_STKSIZ .EQU $FF00 - $ .FILL HBX_STKSIZ,$FF HBX_STACK .EQU $ ; +#IF (INTMODE == 2) +; ; HBIOS INTERRUPT VECTOR TABLE (16 ENTRIES) ; HBX_IVT: @@ -459,6 +493,8 @@ HBX_IVT: .DW INT_BAD ; .DW INT_BAD ; ; +#ENDIF +; ; INTERRUPT HANDLER STUBS ; ; THE FOLLOWING INTERRUPT STUBS RECEIVE CONTROL FROM THE @@ -467,27 +503,37 @@ HBX_IVT: ; ; INT_IM1: +#IF (INTMODE == 1) PUSH HL ; SAVE HL LD HL,HB_IM1INT ; HL := IM1 INT HANDLER IN BIOS BANK JR HBX_INT ; TO TO ROUTING CODE +#ELSE + RETI ; UNEXPECTED INT, RET W/ INTS LEFT DISABLED +#ENDIF ; -INT_TIMER: ; TIMER INTERRUPT HANDLER - PUSH HL ; SAVE HL - LD HL,HB_TIMINT ; HL := INT ADR IN BIOS - JR HBX_INT ; GO TO ROUTING CODE +#IF (INTMODE == 2) ; INT_BAD: ; BAD INTERRUPT HANDLER PUSH HL ; SAVE HL LD HL,HB_BADINT ; HL := INT HANDLER IN BIOS BANK - JR HBX_INT ; TO TO ROUTING CODE + JR HBX_INT ; GO TO ROUTING CODE ; -#IF (SIOENABLE) +INT_TIMER: ; TIMER INTERRUPT HANDLER + PUSH HL ; SAVE HL + LD HL,HB_TIMINT ; HL := INT ADR IN BIOS + JR HBX_INT ; GO TO ROUTING CODE +; + #IF (SIOENABLE) INT_SIO: ; SIO INTERRUPT HANDLER PUSH HL ; SAVE HL LD HL,SIO_INT ; HL := SIO INT HANDLER IN BIOS BANK - JR HBX_INT ; TO TO ROUTING CODE + JR HBX_INT ; GO TO ROUTING CODE + #ENDIF +; #ENDIF ; +#IF (INTMODE > 0) +; ; COMMON INTERRUPT DISPATCHING CODE ; SETUP AND CALL HANDLER IN BIOS BANK ; @@ -501,7 +547,7 @@ HBX_INT: ; COMMON INTERRUPT ROUTING CODE PUSH BC ; SAVE BC PUSH DE ; SAVE DE PUSH IY ; SAVE IY - + LD A,BID_BIOS ; HBIOS BANK CALL HBX_BNKSEL_INT ; SELECT IT @@ -509,7 +555,7 @@ HBX_INT: ; COMMON INTERRUPT ROUTING CODE LD A,(HB_CURBNK) ; GET PRE-INT BANK CALL HBX_BNKSEL ; SELECT IT - + ; RESTORE STATE POP IY ; RESTORE IY POP DE ; RESTORE DE @@ -524,6 +570,8 @@ HBX_INT_SP .EQU $ - 2 EI ; ENABLE INTERRUPTS RETI ; AND RETURN ; +#ENDIF +; ; FILL TO START OF BOUNCE BUFFER ; HBX_INTFILL .EQU (HBX_XFC - HBX_BUFSIZ - $) @@ -605,12 +653,10 @@ HB_START: XOR A OUT0 (Z180_CCR),A OUT0 (Z180_CMR),A - CALL DLY8 ; SETTLE ; SET DEFAULT WAIT STATES LD A,$F0 OUT0 (Z180_DCNTL),A - CALL DLY8 ; SETTLE ; MMU SETUP LD A,$80 @@ -626,14 +672,12 @@ HB_START: ; SET CLOCK DIVIDE TO 1 RESULTING IN FULL XTAL SPEED LD A,$80 OUT0 (Z180_CCR),A - CALL DLY8 ; SETTLE #ENDIF #IF (Z180_CLKDIV >= 2) ; SET CPU MULTIPLIER TO 1 RESULTING IN XTAL * 2 SPEED LD A,$80 OUT0 (Z180_CMR),A - CALL DLY8 ; SETTLE #ENDIF #ENDIF @@ -697,9 +741,6 @@ HB_START: LD DE,0 LD BC,$8000 CALL HBX_BNKCPY -; - ; INTERRUPTS ARE ENABLED BY BNKCPY!!! - DI ; RE-DISABLE INTERRUPTS ; ; TRANSITION TO HBIOS IN RAM BANK ; @@ -708,19 +749,41 @@ HB_START: CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN HALT ; WE SHOULD NOT COME BACK HERE! ; -HB_RAMFLAG .DB FALSE ; ASSUME FALSE, SET TO TRUE BELOW AFTER RAM TRANSITION +HB_RAMFLAG .DB FALSE ; INITIALLY FALSE, SET TO TRUE BELOW AFTER RAM TRANSITION ; ; EXECUTION RESUMES HERE AFTER SWITCH TO RAM BANK ; HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK -; - ; INTERRUPTS ARE ENABLED BY BNKCALL!!! - DI ; RE-DISABLE INTERRUTPS ; LD SP,HBX_LOC ; RESET STACK SINCE WE DO NOT RETURN LD A,TRUE ; ACCUM := TRUE LD (HB_RAMFLAG),A ; SET RAMFLAG ; +; IF APPBOOT, WE NEED TO FIX UP A FEW THINGS IN PAGE ZERO +; +#IFDEF APPBOOT + ; MAKE SURE RST 08 VECTOR IS RIGHT + LD A,$C3 + LD ($0008),A + LD HL,HB_INVOKE + LD ($0009),HL +; + ; MAKE SURE IM1 INT VECTOR IS RIGHT + #IF (INTMODE == 1) + ; JP INT_IM1 IF INTERRUPT MODE ACTIVE + LD A,$C3 + LD ($0038),A + LD HL,INT_IM1 + LD ($0039),HL + #ELSE + ; RETI ($ED, $4D) IF NON-INTERRUPT MODE + LD HL,($0038) + LD (HL),$ED + INC HL + LD (HL),$4D + #ENDIF +#ENDIF +; ; PERFORM DYNAMIC CPU SPEED DERIVATION ; CALL HB_CPUSPD ; CPU SPEED DETECTION @@ -765,12 +828,13 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; NOW THAT HBIOS IS READY, SET THE CONSOLE UNIT TO ACTIVATE CONSOLE I/O ; VIA HBIOS. ; - XOR A ; CONSOLE DEVICE IS UNIT #0 BY FIAT + XOR A ; INITIALLY, FIRST SERIAL UNIT IS CONSOLE LD (CB_CONDEV),A ; SAVE IT, ACTIVATES CONSOLE ON HBIOS ; ; ANNOUNCE HBIOS ; - + CALL NEWLINE2 + PRTX(STR_BANNER) ; ; IO PORT SCAN ; @@ -803,32 +867,49 @@ PSCNX .EQU $ + 1 ; ; SETUP INTERRUPT VECTORS, AS APPROPRIATE ; - HB_DI ; START OF CRITICAL SECTION - -#IF (INTTYPE == IT_SIMH) -; - ; SETUP TIMER INT VECTOR VIA INT MODE 1 IN PAGE ZERO - LD A,$C3 ; JP OPCODE - ;LD ($38),A ; ... AT INT VECTOR ADDRESS - LD ($30),A ; ... AT INT VECTOR ADDRESS - LD HL,INT_TIMER ; ADDRESS OF TIMER INT HANDLER - ;LD ($39),HL ; ... IS TARGET OF JP - LD ($31),HL ; ... IS TARGET OF JP - - LD HL,INT_TIMER - LD (HBX_IVT),HL -; -#ENDIF -; -#IF (INTTYPE == IT_Z180) +;#IF (INTMODE == 1) +; ; OVERLAY $0038 WITH JP INT_IM1 +; LD A,$C3 ; JP INSTRUCTION +; LD ($0038),A ; INSTALL IT +; LD HL,INT_IM1 ; DESTINATION ADDRESS +; LD ($0039),HL ; INSTALL IT +;#ENDIF ; +#IF (INTMODE == 2) + ; SETUP Z80 IVT AND INT MODE 2 ; SETUP Z180 IVT LD A,HBX_IVT >> 8 ; SETUP HI BYTE OF IVT ADDRESS LD I,A ; ... AND PLACE IT IN I REGISTER + + #IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) XOR A ; SETUP LO BYTE OF IVT ADDRESS OUT0 (Z180_IL),A ; ... AND PLACE IN Z180 IL REGISTER -; + #ENDIF + IM 2 ; SWITCH TO INT MODE 2 +#ENDIF + +#IF (PLATFORM == PLT_SBC) +; + #IF (HTIMENABLE) +; + #IF (INTMODE == 1) + LD HL,HB_TIMINT + CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST + #ENDIF +; + #IF (INTMODE == 2) + ;LD HL,INT_TIMER + ;LD (HBX_IVT),HL + #ENDIF +; + #ENDIF +; +#ENDIF +; +#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) +; + #IF (INTMODE == 2) ; ; MASK ALL EXTERNAL INTERRUPTS FOR NOW XOR A ; INT0-2 DISABLED @@ -851,42 +932,12 @@ PSCNX .EQU $ + 1 OUT (C),H LD A,%00010001 ; ENABLE TIMER0 INT AND DOWN COUNTING OUT0 (Z180_TCR),A -; -#ENDIF -; -#IF (INTTYPE == IT_RC) -; - #IF 0 - ; SETUP Z80 IVT AND INT MODE 2 - LD A,HBX_IVT >> 8 ; SETUP HI BYTE OF IVT ADDRESS - LD I,A ; ... AND PLACE IT IN I REGISTER - IM 2 ; SWITCH TO INT MODE 2 -; - #IF (SIOENABLE) - ; SETUP SIO INTERRUPT VECTOR IN IVT - LD HL,INT_SIO - LD (HBX_IVT + IVT_SER0),HL - #ENDIF -; - #ENDIF -; - #IF 1 - ; SET INT MODE 1 - IM 1 -; - #IF (SIOENABLE | ACIAENABLE) - ; SETUP IM1 INT VECTOR VIA INT MODE 1 IN PAGE ZERO - LD A,$C3 ; JP OPCODE - LD ($38),A ; ... AT INT VECTOR ADDRESS - LD HL,INT_IM1 ; ADDRESS OF SIO INT HANDLER - LD ($39),HL ; ... IS TARGET OF JP - #ENDIF ; #ENDIF ; #ENDIF ; - HB_EI ; END OF CRITICAL SECTION + HB_EI ; INTERRUPTS SHOULD BE OK NOW ; ; DISPLAY PLATFORM INFORMATION ; @@ -899,26 +950,37 @@ PSCNX .EQU $ + 1 ; ; DISPLAY CPU CONFIG ; + ;CALL PRTSTRD + ;.TEXT ", $" + CALL NEWLINE #IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) -; - CALL PRTSTRD - .TEXT ", $" LD A,Z180_MEMWAIT +#ELSE + LD A,0 +#ENDIF CALL PRTDECB CALL PRTSTRD .TEXT " MEM W/S, $" - LD A,Z180_IOWAIT +#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) + LD A,Z180_IOWAIT + 1 +#ELSE + LD A,1 +#ENDIF CALL PRTDECB CALL PRTSTRD .TEXT " I/O W/S$" -; +#IF (INTMODE > 0) + CALL PRTSTRD + .TEXT ", INT MODE $" + LD A,INTMODE + CALL PRTDECB #ENDIF ; ; DISPLAY MEMORY CONFIG ; CALL NEWLINE - CALL PRTSTRD - .TEXT "MEMORY LAYOUT $" + ;CALL PRTSTRD + ;.TEXT "MEMORY CONFIG: $" LD HL,ROMSIZE CALL PRTDEC CALL PRTSTRD @@ -994,22 +1056,31 @@ INITSYS3: ; CHAIN TO OS LOADER ; #IFDEF ROMBOOT - ; PERFORM BANK CALL TO OS IMAGES BANK + ; PERFORM BANK CALL TO OS IMAGES BANK IN ROM LD A,BID_OSIMG ; CHAIN TO OS IMAGES BANK LD HL,0 ; ENTER AT ADDRESS 0 CALL HBX_BNKCALL ; GO THERE HALT ; WE SHOULD NEVER COME BACK! #ELSE ; COPY OS IMAGE: BID_USR: --> BID_USR:0 - LD A,BID_USR - LD (HB_SRCBNK),A - LD (HB_DSTBNK),A - LD HL,HB_END - LD DE,0 - LD BC,$8000 - CALL HBX_BNKCPY -; - ; PERFORM BANK CALL TO OS IMAGES BANK + ;LD A,BID_USR + ;LD (HB_SRCBNK),A + ;LD (HB_DSTBNK),A + ;LD HL,HB_END + ;LD DE,0 + ;LD BC,$8000 + ;CALL HBX_BNKCPY + LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY + LD D,BID_USR ; D = DEST BANK = USER BANK + LD E,BID_USR ; E = SRC BANK = USER BANK + LD HL,$8000 ; HL = COPY LEN = ENTIRE BANK + RST 08 ; DO IT + LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY + LD HL,HB_END ; COPY FROM END OF OF HBIOS + LD DE,0 ; TO USER ADDRESS 0 + RST 08 ; DO IT +; + ; PERFORM BANK CALL TO USER BANK LD A,BID_USR ; CHAIN TO OS IMAGES BANK LD HL,0 ; ENTER AT ADDRESS 0 CALL HBX_BNKCALL ; GO THERE @@ -1101,9 +1172,11 @@ IDLE: PUSH BC PUSH DE PUSH HL + PUSH IY #IF (FDENABLE) CALL FD_IDLE #ENDIF + POP IY POP HL POP DE POP BC @@ -1148,14 +1221,14 @@ HB_DISPCALL: CALL C,PANIC ; OBSOLETE! CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER JP C,VDA_DISPATCH - CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0 CALL C,PANIC ; PANIC IF LESS THAN BF_SYS JP SYS_DISPATCH ; OTHERWISE SYS CALL CALL PANIC ; THIS SHOULD NEVER BE REACHED + RET ; ;================================================================================================== -; CHARACTER I/O DEVICE DISPATCHER +; CHARACTER I/O DEVICE FUNCTION DISPATCHER ;================================================================================================== ; ; ROUTE CALL TO SPECIFIED CHARACTER I/O DRIVER @@ -1163,86 +1236,54 @@ HB_DISPCALL: ; C: UNIT NUMBER ; CIO_DISPATCH: -; -; ON ENTRY C IS HBIOS UNIT # (INDEX INTO CIO_TBL OF CHARACTER DEVICES) -; USE UNIT # IN C TO LOOKUP CIO_TBL ENTRY, THEN -; CONVERT C TO THE DEVICE/DRIVER SPECIFIC UNIT ID -; AND GET THE DEVICE TYPE TO A FOR DRIVER DISPATCHING -; + BIT 7,C ; CHECK FOR SPECIAL UNIT CODE + CALL NZ,CIO_SPECIAL ; IF SO, HANDLE IT + PUSH IY ; SAVE INCOMING IY - LD A,C ; INCOMING UNIT INDEX TO A - PUSH HL ; SAVE INCOMING HL - LD HL,CIO_CNT ; HL := ADDRESS OF TABLE ENTRY COUNT PREFIX - CP (HL) ; COMPARE TO INCOMING ENTRY INDEX - JR C,CIO_DISPATCH1 ; UNIT OK, PROCEED - CP CIODEV_CONSOLE ; CHECK FOR SPECIAL VALUE - CONSOLE OUTPUT - JR Z,CIO_DISPATCH_CON ; DO IT -; - ; NOT GOOD, INCOMING UNIT IS OUT OF RANGE - POP HL ; RESTORE HL/STACK - CALL PANIC ; PANIC - OR $FF ; SIGNAL ERROR - RET ; AND RETURN -; -CIO_DISPATCH_CON: - LD A,(CB_CONDEV) ; PUT CONSOLE UNIT NUMBER IN A - ; FALL THRU + + LD IY,CIO_TBL ; POINT IY TO START OF DIO TABLE + CALL HB_DISPCALL ; GO TO GENERIC API CALL CODE + + POP IY ; RESTORE IY + RET ; AND DONE ; -CIO_DISPATCH1: +; SPECIAL HANDLING FOR DEDICATED UNIT CODES ; - ; SET HL := TABLE ENTRY ADDRESS - INC HL ; BUMP PAST COUNT PREFIX TO START OF TABLE ENTRIES - RLCA ; MULTIPLY UNIT # BY 4 TO - RLCA ; ... TO CALC ENTRY OFFSET - CALL ADDHLA ; HL := ADDRESS OF ENTRY IN TABLE +CIO_SPECIAL: + ; FOR NOW, ONLY SPECIAL CODE IS A CONSOLE REQUEST + ; SO JUST SWAP IN ACTIVE CONSOLE UNIT + LD A,(CB_CONDEV) ; GET ACTIVE CONSOLE + LD C,A ; OVERLAY UNIT CODE IN C + RET ; AND REJOIN MAIN DISPATCH FLOW ; - ; GET FIRST WORD OF TABLE ENTRY AND SAVE FOR DRIVER CALL - LD A,(HL) - LD (CIO_TGTADR+0),A - INC HL - LD A,(HL) - LD (CIO_TGTADR+1),A - INC HL +; ADD AN ENTRY TO THE CIO UNIT TABLE (SEE HB_ADDENT FOR DETAILS) ; - ; GET SECOND WORD OF TABLE ENTRY AND PUT IN IY FOR DRIVER CALL - LD A,(HL) ; GET DATA WORD - INC HL ; ... - LD H,(HL) ; ... - LD L,A ; ... INTO HL - EX (SP),HL ; RESTORE HL & MOVE BLOB ADR TO (SP) - POP IY ; BLOB ADR TO IY - - ; CALL DRIVER (ADDRESS BYTES OF CALL INSTRUCTION UPDATED ABOVE) - CALL PANIC ; CALL DRIVER DISPATCH ENTRY -CIO_TGTADR .EQU $ - 2 ; REFERENCE TO ADDRESS OF CALL INSTRUCTION - POP IY ; RESTORE ORIGINAL IY - RET ; AND RETURN +CIO_ADDENT: + LD HL,CIO_TBL ; POINT TO CIO TABLE + JP HB_ADDENT ; ... AND GO TO COMMON CODE ; ; HBIOS CHARACTER DEVICE UNIT TABLE ; ; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. ; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT ; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. +; TABLE - 3 CONTAINS THE NUMBER OF CIO FUNCTION IDS ; EACH ENTRY IS DEFINED AS: ; -; WORD DRIVER DISPATCH ENTRY ADDRESS +; WORD DRIVER FUNCTION TABLE ADDRESS ; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) ; -CIO_MAX .EQU 16 ; UP TO 16 UNITS -CIO_SIZ .EQU CIO_MAX * 4 ; EACH ENTRY IS 4 BYTES -; - .DB CIO_MAX ; MAX ENTRY COUNT TABLE PREFIX -CIO_CNT .DB 0 ; ENTRY COUNT PREFIX -CIO_TBL .FILL CIO_SIZ,0 ; SPACE FOR ENTRIES -; -; ADD AN ENTRY TO THE CIO UNIT TABLE (SEE HB_ADDENT FOR DETAILS) -; -CIO_ADDENT: - LD HL,CIO_TBL ; POINT TO CIO TABLE - JP HB_ADDENT ; ... AND GO TO COMMON CODE +CIO_FNCNT .EQU 7 ; NUMBER OF CIO FUNCS (FOR RANGE CHECK) +CIO_MAX .EQU 16 ; UP TO 16 UNITS +CIO_SIZ .EQU CIO_MAX * 4 ; EACH ENTRY IS 4 BYTES +; + .DB CIO_FNCNT ; CIO FUNCTION COUNT (FOR RANGE CHECK) + .DB CIO_MAX ; MAX ENTRY COUNT TABLE PREFIX +CIO_CNT .DB 0 ; ENTRY COUNT PREFIX +CIO_TBL .FILL CIO_SIZ,0 ; SPACE FOR ENTRIES ; ;================================================================================================== -; DISK I/O DEVICE DISPATCHER +; DISK I/O DEVICE FUNCTION DISPATCHER ;================================================================================================== ; ; ROUTE CALL TO SPECIFIED DISK I/O DRIVER @@ -1269,113 +1310,40 @@ DIO_DISPATCH: ; #ENDIF ; *DEBUG* END ; -; ON ENTRY C IS HBIOS UNIT # (INDEX INTO DIO_TBL OF DISK DEVICES) -; USE UNIT # IN C TO LOOKUP DIO_TBL ENTRY. THE DIO_TBL -; ENTRY CONTAINS THE START OF THE DRIVER FUNCTION TABLE AND -; THE DEVICE SPECIFIC INSTANCE DATA (BLOB). SET IY TO BLOB ADDRESS -; AND CALL THE SPECIFIC FUNCTION REQUESTED IN THE DRIVER. -; DIO_DISPCALL: PUSH IY ; SAVE INCOMING IY - ; SETUP TO RESTORE IY AT EXIT - LD IY,DIO_DISPEXIT ; PRIME STACK WITH - PUSH IY ; ... RETURN VECTOR - - ; START WITH IY POINTING TO START OF DIO_TBL LD IY,DIO_TBL ; POINT IY TO START OF DIO TABLE - - ; CHECK INCOMING UNIT INDEX IN C FOR VAILIDITY - LD A,C ; A := INCOMING DISK UNIT INDEX - CP (IY-1) ; COMPARE TO COUNT - JR NC,DIO_DISPERR ; HANDLE INVALID UNIT INDEX - - ; CHECK FUNCTION INDEX FOR VALIDITY - LD A,B ; A := INCOMING FUNCTION NUMBER - AND $0F ; LOW NIBBLE ONLY FOR FUNC INDEX - CP DIO_FNCNT ; COMPARE TO DIO FUNCTION COUNT IN A - JR NC,DIO_DISPERR ; HANDLED INVALID FUNCTION NUMBER - - ; BUMP IY TO ACTUAL DIO_TBL ENTRY FOR INCOMING UNIT INDEX - LD B,0 ; MSB IS ALWAYS ZERO - RLC C ; MULTIPLY UNIT INDEX - RLC C ; ... BY 4 FOR TABLE ENTRY OFFSET - ADD IY,BC ; SET IY TO ENTRY ADDRESS - - ; DERIVE DRIVER FUNC ADR TO CALL - PUSH HL ; SAVE INCOMING HL - LD L,(IY+0) ; COPY DRIVER FUNC TABLE - LD H,(IY+1) ; ... START TO HL - RLCA ; CONV UNIT (STILL IN A) TO FN ADR OFFSET - CALL ADDHLA ; HL NOW HAS DRIVER FUNC TBL START ADR - LD A,(HL) ; DEREFERENCE HL - INC HL ; ... TO GET - LD H,(HL) ; ... ACTUAL - LD L,A ; ... TARGET FUNCTION ADDRESS - EX (SP),HL ; RESTORE HL, FUNC ADR ON STACK - - ; GET UNIT INSTANCE DATA BLOB ADDRESS TO IY - PUSH HL ; SAVE INCOMING HL - LD L,(IY+2) ; HL := DATA BLOB ADDRESS - LD H,(IY+3) ; ... - EX (SP),HL ; RESTORE HL, BLOB ADR ON TOS - POP IY ; IY := BLOB ADR - - RET ; JUMP TO DRIVER FUNC ADR ON TOS + CALL HB_DISPCALL ; GO TO GENERIC API CALL CODE + + POP IY ; RESTORE IY + RET ; AND DONE ; -DIO_DISPEXIT: - POP IY ; RECOVER ORIGINAL INCOMING IY - RET ; AND RETURN TO CALLER +; ADD AN ENTRY TO THE DIO UNIT TABLE ; -DIO_DISPERR: - CALL PANIC ; PANIC - OR $FF ; SIGNAL ERROR - RET ; AND RETURN VIA DISPEXIT +DIO_ADDENT: + LD HL,DIO_TBL ; POINT TO DIO TABLE + JP HB_ADDENT ; ... AND GO TO COMMON CODE ; ; HBIOS DISK DEVICE UNIT TABLE ; ; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. ; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT ; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. +; TABLE - 3 CONTAINS THE NUMBER OF DIO FUNCTION IDS ; EACH ENTRY IS DEFINED AS: ; -; WORD DRIVER DISPATCH ENTRY ADDRESS +; WORD DRIVER FUNCTION TABLE ADDRESS ; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) ; -DIO_MAX .EQU 16 ; UP TO 16 UNITS -DIO_SIZ .EQU DIO_MAX * 4 ; EACH ENTRY IS 4 BYTES -; - .DB DIO_MAX ; MAX ENTRY COUNT TABLE PREFIX -DIO_CNT .DB 0 ; ENTRY COUNT PREFIX -DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES -; -; ADD AN ENTRY TO THE DIO UNIT TABLE -; -DIO_ADDENT: - LD HL,DIO_TBL ; POINT TO DIO TABLE - JP HB_ADDENT ; ... AND GO TO COMMON CODE -; -; CONVERT AN HBIOS STANDARD HARD DISK CHS ADDRESS TO -; AN LBA ADDRESS. A STANDARD HBIOS HARD DISK IS ASSUMED -; TO HAVE 16 SECTORS PER TRACK AND 16 HEADS PER CYLINDER. -; -; INPUT: HL=TRACK, D=HEAD, E=SECTOR -; OUTPUT: DE:HL=32 BIT LBA ADDRESS (D:7 IS NOT SET IN THE RESULT) -; -HB_CHS2LBA: -; - LD A,D ; HEAD TO A - RLCA ; LEFT SHIFT TO HIGH NIBBLE - RLCA ; ... DEPENDS ON HIGH - RLCA ; ... NIBBLE BEING 0 SINCE - RLCA ; ... IT ROTATES INTO LOW NIBBLE - OR E ; COMBINE WITH SECTOR (HIGH NIBBLE MUST BE ZERO) - LD D,0 - LD E,H - LD H,L - LD L,A - XOR A - RET +DIO_FNCNT .EQU 12 ; NUMBER OF DIO FUNCS (FOR RANGE CHECK) +DIO_MAX .EQU 16 ; UP TO 16 UNITS +DIO_SIZ .EQU DIO_MAX * 4 ; EACH ENTRY IS 4 BYTES +; + .DB DIO_FNCNT ; DIO FUNCTION COUNT (FOR RANGE CHECK) + .DB DIO_MAX ; MAX ENTRY COUNT TABLE PREFIX +DIO_CNT .DB 0 ; ENTRY COUNT PREFIX +DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES ; ;================================================================================================== ; REAL TIME CLOCK DEVICE DISPATCHER @@ -1402,80 +1370,39 @@ RTC_DISPATCH: ; C: UNIT NUMBER ; VDA_DISPATCH: -; -; ON ENTRY C IS HBIOS UNIT # (INDEX INTO VDA_TBL OF VIDEO DEVICES) -; USE UNIT # IN C TO LOOKUP VDA_TBL ENTRY, THEN -; CONVERT C TO THE DEVICE/DRIVER SPECIFIC UNIT ID -; AND GET THE DEVICE TYPE TO A FOR DRIVER DISPATCHING -; PUSH IY ; SAVE INCOMING IY - LD A,C ; INCOMING UNIT INDEX TO A - PUSH HL ; SAVE INCOMING HL - LD HL,VDA_CNT ; HL := ADDRESS OF TABLE ENTRY COUNT - CP (HL) ; COMPARE TO INCOMING ENTRY INDEX - JR C,VDA_DISPATCH1 ; UNIT OK, PROCEED -; - ; NOT GOOD, INCOMING UNIT IS OUT OF RANGE - POP HL ; RESTORE HL/STACK - CALL PANIC ; PANIC - OR $FF ; SIGNAL ERROR - RET ; AND RETURN -; -VDA_DISPATCH1: + + LD IY,VDA_TBL ; POINT IY TO START OF DIO TABLE + CALL HB_DISPCALL ; GO TO GENERIC API CALL CODE + + POP IY ; RESTORE IY + RET ; AND DONE ; - ; SET HL := TABLE ENTRY ADDRESS - INC HL ; BUMP PAST COUNT PREFIX TO START OF TABLE ENTRIES - RLCA ; MULTIPLY UNIT # BY 4 TO - RLCA ; ... TO CALC ENTRY OFFSET - CALL ADDHLA ; HL := ADDRESS OF ENTRY IN TABLE +; ADD AN ENTRY TO THE VDA UNIT TABLE (SEE HB_ADDENT FOR DETAILS) ; - ; GET FIRST WORD OF TABLE ENTRY AND SAVE FOR DRIVER CALL - LD A,(HL) ; DEREFERENCE - INC HL ; ... - PUSH HL ; SAVE IT FOR BELOW - LD H,(HL) ; ... - LD L,A ; ... SO HL HAS ADDRESS OF DRIVER DISPATCH - LD (VDA_TGTADR),HL ; SAVE THE TARGET ADDRESS TO CALL LATER -; - ; GET SECOND WORD OF TABLE ENTRY AND PUT IN IY FOR DRIVER CALL - POP HL ; GET TABLE ENTRY ADDRESS BACK - INC HL ; INCREMENT TO DATA WORD - LD A,(HL) ; GET DATA WORD - INC HL ; ... - LD H,(HL) ; ... - LD L,A ; ... INTO HL - PUSH HL ; AND COPY IT - POP IY ; ... TO IY -; - ; CALL DRIVER (ADDRESS BYTES OF CALL INSTRUCTION UPDATED ABOVE) - POP HL ; GET ORIGINAL HL BACK (10) - CALL PANIC ; CALL DRIVER DISPATCH ENTRY -VDA_TGTADR .EQU $ - 2 ; REFERENCE TO ADDRESS OF CALL INSTRUCTION - POP IY ; RESTORE ORIGINAL IY - RET ; AND RETURN +VDA_ADDENT: + LD HL,VDA_TBL ; POINT TO VDA TABLE + JP HB_ADDENT ; ... AND GO TO COMMON CODE ; ; HBIOS VIDEO DEVICE UNIT TABLE ; ; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. ; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT ; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. +; TABLE - 3 CONTAINS THE NUMBER OF CIO FUNCTION IDS ; EACH ENTRY IS DEFINED AS: ; -; WORD DRIVER DISPATCH ADDRESS -; WORD UNIT DATA ADDRESS -; -VDA_MAX .EQU 16 ; UP TO 16 UNITS -VDA_SIZ .EQU VDA_MAX * 4 ; EACH ENTRY IS 4 BYTES -; - .DB VDA_MAX ; MAX ENTRY COUNT TABLE PREFIX -VDA_CNT .DB 0 ; ENTRY COUNT PREFIX -VDA_TBL .FILL VDA_SIZ,0 ; SPACE FOR ENTRIES +; WORD DRIVER FUNCTION TABLE ADDRESS +; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) ; -; ADD AN ENTRY TO THE VDA UNIT TABLE (SEE HB_ADDENT FOR DETAILS) +VDA_FNCNT .EQU 15 ; NUMBER OF VDA FUNCS (FOR RANGE CHECK) +VDA_MAX .EQU 16 ; UP TO 16 UNITS +VDA_SIZ .EQU VDA_MAX * 4 ; EACH ENTRY IS 4 BYTES ; -VDA_ADDENT: - LD HL,VDA_TBL ; POINT TO VDA TABLE - JP HB_ADDENT ; ... AND GO TO COMMON CODE + .DB VDA_FNCNT ; VDA FUNCTION COUNT (FOR RANGE CHECK) + .DB VDA_MAX ; MAX ENTRY COUNT TABLE PREFIX +VDA_CNT .DB 0 ; ENTRY COUNT PREFIX +VDA_TBL .FILL VDA_SIZ,0 ; SPACE FOR ENTRIES ; ;================================================================================================== ; SYSTEM FUNCTION DISPATCHER @@ -1511,6 +1438,27 @@ SYS_DISPATCH: JP Z,SYS_POKE ; $FB CALL PANIC ; INVALID ; +; SOFT RESET HBIOS, RELEASE HEAP MEMORY NOT USED BY HBIOS +; +SYS_RESET: + LD HL,(HEAPCURB) ; GET HBIOS HEAP THRESHOLD + LD (CB_HEAPTOP),HL ; RESTORE HEAP TOP + XOR A + RET +; +; GET THE CURRENT HBIOS VERSION +; ON INPUT, C=0 +; RETURNS VERSION IN DE AS BCD +; D: MAJOR VERION IN TOP 4 BITS, MINOR VERSION IN LOW 4 BITS +; E: UPDATE VERION IN TOP 4 BITS, PATCH VERSION IN LOW 4 BITS +; L: PLATFORM ID +; +SYS_VER: + LD DE,0 | (RMJ << 12) | (RMN << 8) | (RUP << 4) | RTP + LD L,PLATFORM + XOR A + RET +; ; SET ACTIVE MEMORY BANK AND RETURN PREVIOUSLY ACTIVE MEMORY BANK ; NOTE THAT IT GOES INTO EFFECT AS HBIOS FUNCTION IS EXITED ; HERE, WE JUST SET THE CURRENT BANK @@ -1558,7 +1506,13 @@ SYS_BNKCPY: LD HL,(HB_CPYLEN) ; HL := COPY LEN (SAVED IN SETCPY) EX (SP),HL ; RESTORE HL & SET (SP) TO COPY LEN POP BC ; BC := COPY LEN +#IF (INTMODE == 1) + DI +#ENDIF CALL HB_BNKCPY +#IF (INTMODE == 1) + EI +#ENDIF XOR A RET ; @@ -1582,19 +1536,6 @@ SYS_FREE: OR $FF RET ; -; GET THE CURRENT HBIOS VERSION -; ON INPUT, C=0 -; RETURNS VERSION IN DE AS BCD -; D: MAJOR VERION IN TOP 4 BITS, MINOR VERSION IN LOW 4 BITS -; E: UPDATE VERION IN TOP 4 BITS, PATCH VERSION IN LOW 4 BITS -; L: PLATFORM ID -; -SYS_VER: - LD DE,0 | (RMJ << 12) | (RMN << 8) | (RUP << 4) | RTP - LD L,PLATFORM - XOR A - RET -; ; GET SYSTEM INFORMATION ; ITEM TO RETURN INDICATED IN C ; @@ -1606,6 +1547,8 @@ SYS_GET: JR Z,SYS_GETDIOCNT CP BF_SYSGET_VDACNT JR Z,SYS_GETVDACNT + CP BF_SYSGET_TIMER + JR Z,SYS_GETTIMER CP BF_SYSGET_BOOTINFO JR Z,SYS_GETBOOTINFO CP BF_SYSGET_CPUINFO @@ -1617,6 +1560,18 @@ SYS_GET: OR $FF ; SIGNAL ERROR RET ; +; GET TIMER +; RETURNS: +; DE:HL: TIMER VALUE (32 BIT) +; +SYS_GETTIMER: + LD HL,HB_TICKS + HB_DI + CALL LD32 + HB_EI + XOR A + RET +; ; GET BOOT INFORMATION ; RETURNS: ; L: BOOT BANK ID @@ -1696,6 +1651,8 @@ SYS_GETVDACNT: ; SYS_SET: LD A,C ; GET REQUESTED SUB-FUNCTION + CP BF_SYSSET_TIMER + JR Z,SYS_SETTIMER CP BF_SYSSET_BOOTINFO JR Z,SYS_SETBOOTINFO OR $FF ; SIGNAL ERROR @@ -1713,12 +1670,30 @@ SYS_SETBOOTINFO: XOR A RET ; +; SET TIMER +; ON ENTRY: +; DE:HL: TIMER VALUE (32 BIT) +; +SYS_SETTIMER: + LD BC,HB_TICKS + HB_DI + CALL ST32 + HB_EI + XOR A + RET +; ; RETURN A BYTE OF MEMORY FROM SPECIFIED BANK ; ENTRY: D=BANK ID, HL=ADDRESS ; RETURN: E=BYTE VALUE ; SYS_PEEK: +#IF (INTMODE == 1) + DI +#ENDIF CALL HBX_PEEK ; IMPLEMENTED IN PROXY +#IF (INTMODE == 1) + EI +#ENDIF XOR A RET ; @@ -1726,15 +1701,13 @@ SYS_PEEK: ; ENTRY: D=BANK ID, HL=ADDRESS IN HBIOS BANK, E=BYTE VALUE ; SYS_POKE: +#IF (INTMODE == 1) + DI +#ENDIF CALL HBX_POKE ; IMPLEMENTED IN PROXY - XOR A - RET -; -; SOFT RESET HBIOS, RELEASE HEAP MEMORY NOT USED BY HBIOS -; -SYS_RESET: - LD HL,(HEAPCURB) ; GET HBIOS HEAP THRESHOLD - LD (CB_HEAPTOP),HL ; RESTORE HEAP TOP +#IF (INTMODE == 1) + EI +#ENDIF XOR A RET ; @@ -1754,6 +1727,8 @@ CIO_IDLE: POP AF ; RECOVER AF RET ; +#IF (INTMODE == 1) +; ; IM1 INTERRUPTS ARRIVE HERE AFTER BANK SWITCH TO HBIOS BANK ; LIST OF IM1 INT CALLS IS BUILT DYNAMICALLY BELOW ; SEE HB_ADDIM1 ROUTINE @@ -1762,6 +1737,7 @@ CIO_IDLE: ; RET NZ ; RETURN IF HANDLED ; HB_IM1INT: ; IM1 DEVICE INTERRUPT HANDLER + JP HB_BADINT RET ; START WITH NO ENTRIES .FILL 4 * 8,$C9 ; ROOM FOR 8 ENTRIES ; @@ -1783,7 +1759,9 @@ HB_ADDIM1: LD (HB_IM1P),HL ; SAVE POINTER RET ; DONE ; -HB_IM1P .DW HB_IM1INT ; POINTER FOR NEXT IM1 ENTRY +HB_IM1P .DW HB_IM1INT ; POINTER FOR NEXT IM1 ENTRY +; +#ENDIF ; ; TIMER INTERRUPT ; @@ -1820,12 +1798,13 @@ TEMPCNT .DB 250 ; HB_TIMINT2: ; -#IF (INTTYPE == IT_Z180) - ; ACK/RESET INTERRUPT +#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) + ; ACK/RESET Z180 TIMER INTERRUPT IN0 A,(Z180_TCR) IN0 A,(Z180_TMDR0L) #ENDIF ; + OR $FF ; NZ SET TO INDICATE INT HANDLED RET ; ; BAD INTERRUPT HANDLER @@ -1837,10 +1816,62 @@ HB_BADINT: CALL CONTINUE RET ; +; COMMON API FUNCTION DISPATCH CODE +; +; ON ENTRY C IS UNIT # (INDEX INTO XXX_TBL OF UNITS) +; AND IY POINTS TO START OF UNIT TABLE. +; USE UNIT # IN C TO LOOKUP XXX_TBL ENTRY. THE XXX_TBL +; ENTRY CONTAINS THE START OF THE DRIVER FUNCTION TABLE AND +; THE DEVICE SPECIFIC INSTANCE DATA (BLOB). SET IY TO BLOB ADDRESS +; AND CALL THE SPECIFIC FUNCTION REQUESTED IN THE DRIVER. +; +HB_DISPCALL: + ; CHECK INCOMING UNIT INDEX IN C FOR VAILIDITY + LD A,C ; A := INCOMING DISK UNIT INDEX + CP (IY-1) ; COMPARE TO COUNT + JR NC,HB_DISPERR ; HANDLE INVALID UNIT INDEX + + ; CHECK FUNCTION INDEX FOR VALIDITY + LD A,B ; A := INCOMING FUNCTION NUMBER + AND $0F ; LOW NIBBLE ONLY FOR FUNC INDEX + CP (IY-3) ; CHECK FN NUM AGAINST MAX + JR NC,HB_DISPERR ; HANDLE FN NUM OUT OF RANGE ERROR + + ; BUMP IY TO ACTUAL XXX_TBL ENTRY FOR INCOMING UNIT INDEX + LD B,0 ; MSB IS ALWAYS ZERO + RLC C ; MULTIPLY UNIT INDEX + RLC C ; ... BY 4 FOR TABLE ENTRY OFFSET + ADD IY,BC ; SET IY TO ENTRY ADDRESS + + ; DERIVE DRIVER FUNC ADR TO CALL + PUSH HL ; SAVE INCOMING HL + LD L,(IY+0) ; COPY DRIVER FUNC TABLE + LD H,(IY+1) ; ... START TO HL + RLCA ; CONV UNIT (STILL IN A) TO FN ADR OFFSET + CALL ADDHLA ; HL NOW HAS DRIVER FUNC TBL START ADR + LD A,(HL) ; DEREFERENCE HL + INC HL ; ... TO GET + LD H,(HL) ; ... ACTUAL + LD L,A ; ... TARGET FUNCTION ADDRESS + EX (SP),HL ; RESTORE HL, FUNC ADR ON STACK + + ; GET UNIT INSTANCE DATA BLOB ADDRESS TO IY + PUSH HL ; SAVE INCOMING HL + LD L,(IY+2) ; HL := DATA BLOB ADDRESS + LD H,(IY+3) ; ... + EX (SP),HL ; RESTORE HL, BLOB ADR ON TOS + POP IY ; IY := BLOB ADR + + RET ; JUMP TO DRIVER FUNC ADR ON TOS +; +HB_DISPERR: + CALL PANIC ; PANIC + OR $FF ; SIGNAL ERROR + RET ; AND RETURN VIA DISPEXIT +; ; ADD AN ENTRY TO THE UNIT TABLE AT ADDRESS IN HL -; C: DEVICE TYPE ID -; B: UNIT INDEX -; DE: ADDRESS OF UNIT DATA +; BC: DRIVER FUNCTION TABLE +; DE: ADDRESS OF UNIT INSTANCE DATA ; RETURN ; A: UNIT NUMBER ASSIGNED ; @@ -1863,7 +1894,7 @@ HB_ADDENT: EX (SP),HL ; ... AND DISPATCH ADDRESS TO HL POP BC ; ... SO THAT DE:HL HAS 32 BIT ENTRY CALL ST32 ; LD (BC),DE:HL STORES THE ENTRY - POP AF ; RETURN ENTRY INDEX + POP AF ; RETURN ENTRY INDEX (UNIT NUMBER ASSIGNED) RET ; ; ALLOCATE HL BYTES OF MEMORY ON THE HEAP @@ -2410,7 +2441,7 @@ PS_DISK: PRTS("Disk $") LD A,C ; MOVE UNIT NUM TO A CALL PRTDECB ; PRINT IT, ASSUME SINGLE DIGIT - PRTS(" $") ; PAD TO NEXT COLUMN + PRTS(" $") ; PAD TO NEXT COLUMN ; ; DEVICE COLUMN LD B,BF_DIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C @@ -2562,7 +2593,7 @@ PS_SERIAL: ; ; DEVICE COLUMN LD B,BF_CIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C - RST 08 ; DE:=DEVTYP/NUM, C:=DISK ATTRIBUTES + RST 08 ; DE:=DEVTYP/NUM, C:=DEVICE ATTRIBUTES PUSH BC ; SAVE ATTRIBUTES LD HL,PS_SDSTRREF ; POINT TO SERIAL DEVICE TYPE NAME TABLE CALL PS_PRTDEV ; PRINT SERIAL DEVICE NMEMONIC PADDED TO FIELD WIDTH @@ -2570,7 +2601,7 @@ PS_SERIAL: PUSH BC ; SAVE ATTRIBUTES AGAIN CALL PS_PRTST ; PRINT SERIAL TYPE POP BC ; RESTORE ATTRIBUTES - POP DE ; RESTORE UNIT NUM + POP DE ; RESTORE UNIT NUM TO E CALL PS_PRTSC ; PRINT SERIAL CONFIG ; CALL NEWLINE @@ -2591,7 +2622,7 @@ PS_PRTST1: CALL PS_PAD ; PAD N SPACES (SPECIFIED IN A) RET ; -; PRINT SERIAL CONFIG (UNIT IN C, ATTRIBUTE IN E) +; PRINT SERIAL CONFIG (UNIT IN E, ATTRIBUTE IN C) ; PS_PRTSC: BIT 7,C ; 0=RS-232, 1=TERMINAL @@ -2599,6 +2630,7 @@ PS_PRTSC: ; ; PRINT RS-232 CONFIG LD B,BF_CIOQUERY ; HBIOS FUNC: GET CIO CONFIG + LD C,E ; SET SERIAL UNIT NUM RST 08 ; DE:HL := BAUD RATE LD A,D ; TEST FOR $FF AND E @@ -2685,7 +2717,7 @@ PS_VIDEO: PRTS("Video $") LD A,C ; MOVE UNIT NUM TO A CALL PRTDECB ; PRINT IT, ASSUME SINGLE DIGIT - PRTS(" $") ; PAD TO NEXT COLUMN + PRTS(" $") ; PAD TO NEXT COLUMN ; ; DEVICE COLUMN LD B,BF_VDADEV ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C @@ -2880,8 +2912,8 @@ PS_VTCRT .TEXT "CRT$" ; ; 0 1 2 3 4 5 6 7 ; 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n" - .TEXT "---------- ---------- ---------------- --------------------\r\n$" +PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n" + .TEXT "---------- ---------- ---------------- --------------------\r\n$" ; ;================================================================================================== ; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED) @@ -2997,6 +3029,28 @@ LDHLIYA: INC H ; IF CF SET, BUMP MSB RET ; ... AND RETURN ; +; CONVERT AN HBIOS STANDARD HARD DISK CHS ADDRESS TO +; AN LBA ADDRESS. A STANDARD HBIOS HARD DISK IS ASSUMED +; TO HAVE 16 SECTORS PER TRACK AND 16 HEADS PER CYLINDER. +; +; INPUT: HL=TRACK, D=HEAD, E=SECTOR +; OUTPUT: DE:HL=32 BIT LBA ADDRESS (D:7 IS NOT SET IN THE RESULT) +; +HB_CHS2LBA: +; + LD A,D ; HEAD TO A + RLCA ; LEFT SHIFT TO HIGH NIBBLE + RLCA ; ... DEPENDS ON HIGH + RLCA ; ... NIBBLE BEING 0 SINCE + RLCA ; ... IT ROTATES INTO LOW NIBBLE + OR E ; COMBINE WITH SECTOR (HIGH NIBBLE MUST BE ZERO) + LD D,0 + LD E,H + LD H,L + LD L,A + XOR A + RET +; ;================================================================================================== ; HBIOS GLOBAL DATA ;================================================================================================== @@ -3010,6 +3064,7 @@ HB_TICKS .FILL 4,0 ; 32 BIT TICK COUNTER STR_BANNER .DB "RetroBrew HBIOS v", BIOSVER, ", ", TIMESTAMP, "$" STR_PLATFORM .DB PLATFORM_NAME, "$" STR_SWITCH .DB "*** Activating CRT Console ***$" +STR_BADINT .DB "\r\n*** BAD INT ***\r\n$" ; HB_CURSEC .DB 0 ; CURRENT SECOND (TEMP) ; diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index f68e170d..9e565e6f 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -69,11 +69,13 @@ BF_SYSPOKE .EQU BF_SYS + 11 ; SET A BYTE VALUE IN ALT BANK BF_SYSGET_CIOCNT .EQU $00 ; GET CHAR UNIT COUNT BF_SYSGET_DIOCNT .EQU $10 ; GET DISK UNIT COUNT BF_SYSGET_VDACNT .EQU $40 ; GET VDA UNIT COUNT +BF_SYSGET_TIMER .EQU $D0 ; GET CURRENT TIMER VALUE BF_SYSGET_BOOTINFO .EQU $E0 ; GET BOOT INFORMATION BF_SYSGET_CPUINFO .EQU $F0 ; GET CPU INFORMATION BF_SYSGET_MEMINFO .EQU $F1 ; GET MEMORY CAPACTITY INFO BF_SYSGET_BNKINFO .EQU $F2 ; GET BANK ASSIGNMENT INFO ; +BF_SYSSET_TIMER .EQU $D0 ; SET TIMER VALUE BF_SYSSET_BOOTINFO .EQU $E0 ; SET BOOT INFORMATION ; ; SERIAL DEVICE IDS diff --git a/Source/HBIOS/ppp.asm b/Source/HBIOS/ppp.asm index 5d2e595c..ec4782a6 100644 --- a/Source/HBIOS/ppp.asm +++ b/Source/HBIOS/ppp.asm @@ -247,43 +247,48 @@ PPP_FWVER .DB $00, $00, $00, $00 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD) ; PARPORTPROP CONSOLE DRIVER ;================================================================================================== ; +PPPCON_ROWS .EQU 37 ; PROPELLER VGA DISPLAY ROWS (40 - 3 STATUS LINES) +PPPCON_COLS .EQU 80 ; PROPELLER VGA DISPLAY COLS +; PPPCON_INIT: CALL NEWLINE PRTS("PPPCON:$") +; + ; DISPLAY CONSOLE DIMENSIONS + CALL PC_SPACE + LD A,PPPCON_COLS + CALL PRTDECB + LD A,'X' + CALL COUT + LD A,PPPCON_ROWS + CALL PRTDECB + CALL PRTSTRD + .TEXT " TEXT (ANSI)$" ; ; ADD OURSELVES TO CIO DISPATCH TABLE ; - ;LD B,0 ; PHYSICAL UNIT IS ZERO - ;LD C,CIODEV_PPPCON ; DEVICE TYPE - ;LD DE,0 ; UNIT DATA BLOB ADDRESS LD D,0 ; PHYSICAL UNIT IS ZERO LD E,CIODEV_PPPCON ; DEVICE TYPE - LD BC,PPPCON_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,PPPCON_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE ; XOR A RET ; -; DISPATCH FOR CONSOLE SUBFUNCTIONS -; -PPPCON_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,PPPCON_IN ; JUMP IF CHARACTER IN - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_OUT ; JUMP IF CHARACTER OUT - DEC A ; NEXT SUBFUCNTION - JR Z,PPPCON_IST ; JUMP IF INPUT STATUS - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_OST ; JUMP IF OUTPUT STATUS - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_INITDEV ; JUMP IF INIT DEVICE - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_QUERY ; JUMP IF QUERY - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_DEVICE ; JUMP IF DEVICE REPORT - CALL PANIC ; OTHERWISE SOMETHING IS BADLY BROKEN +; DRIVER FUNCTION TABLE +; +PPPCON_FNTBL: + .DW PPPCON_IN + .DW PPPCON_OUT + .DW PPPCON_IST + .DW PPPCON_OST + .DW PPPCON_INITDEV + .DW PPPCON_QUERY + .DW PPPCON_DEVICE +#IF (($ - PPPCON_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID PPPCON FUNCTION TABLE ***\n" +#ENDIF ; ; CHARACTER INPUT ; WAIT FOR A CHARACTER AND RETURN IT IN E diff --git a/Source/HBIOS/prp.asm b/Source/HBIOS/prp.asm index 57c159d5..9444eafd 100644 --- a/Source/HBIOS/prp.asm +++ b/Source/HBIOS/prp.asm @@ -118,46 +118,51 @@ PRPCON_ERR .EQU $40 ; BIT SET WHEN PROPIO CONSOLE ERROR HAS OCCURRED PRPCON_KBDRDY .EQU $20 ; BIT SET WHEN KEYBOARD BUF HAS A BYTE READY (BUF FULL) PRPCON_DSPRDY .EQU $10 ; BIT SET WHEN DISPLAY BUF IS READY FOR A BYTE (BUF EMPTY) ; +PRPCON_ROWS .EQU 37 ; PROPELLER VGA DISPLAY ROWS (40 - 3 STATUS LINES) +PRPCON_COLS .EQU 80 ; PROPELLER VGA DISPLAY COLS +; ; ; PRPCON_INIT: ; CALL NEWLINE - PRTS("PRPCON:$") + PRTS("PRPCON: $") +; + ; DISPLAY CONSOLE DIMENSIONS + CALL PC_SPACE + LD A,PRPCON_COLS + CALL PRTDECB + LD A,'X' + CALL COUT + LD A,PRPCON_ROWS + CALL PRTDECB + CALL PRTSTRD + .TEXT " TEXT (ANSI)$" ; ; ADD OURSELVES TO CIO DISPATCH TABLE ; - ;LD B,0 ; PHYSICAL UNIT IS ZERO - ;LD C,CIODEV_PRPCON ; DEVICE TYPE - ;LD DE,0 ; UNIT DATA BLOB ADDRESS LD D,0 ; PHYSICAL UNIT IS ZERO LD E,CIODEV_PRPCON ; DEVICE TYPE - LD BC,PRPCON_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,PRPCON_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE ; XOR A ; SIGNAL SUCCESS RET ; -; -; -PRPCON_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,PRPCON_IN - DEC A - JR Z,PRPCON_OUT - DEC A - JR Z,PRPCON_IST - DEC A - JR Z,PRPCON_OST - DEC A - JR Z,PRPCON_INITDEV - DEC A - JR Z,PRPCON_QUERY - DEC A - JR Z,PRPCON_DEVICE - CALL PANIC +; DRIVER FUNCTION TABLE +; +PRPCON_FNTBL: + .DW PRPCON_IN + .DW PRPCON_OUT + .DW PRPCON_IST + .DW PRPCON_OST + .DW PRPCON_INITDEV + .DW PRPCON_QUERY + .DW PRPCON_DEVICE +#IF (($ - PRPCON_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID PRPCON FUNCTION TABLE ***\n" +#ENDIF ; ; ; diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index b2f368cf..c2a0fdc5 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -11,7 +11,7 @@ MONIMG .EQU $1000 CPMIMG .EQU $2000 ZSYSIMG .EQU $5000 ; -INT_IM1 .EQU $FF20 +INT_IM1 .EQU $FF00 ; .ORG 0 ; @@ -38,9 +38,13 @@ INT_IM1 .EQU $FF20 RET ; RST 30 .FILL (038H - $),0FFH #IF (PLATFORM == PLT_UNA) - RETI ; INT + RETI ; RETURN W/ INTS DISABLED #ELSE - JP INT_IM1 ; GO TO HBIOS IM1 INT HANDLER + #IF (INTMODE == 1) + JP INT_IM1 ; JP TO INTERRUPT HANDLER IN HI MEM + #ELSE + RETI ; RETURN W/ INTS DISABLED + #ENDIF #ENDIF .FILL (066H - $),0FFH RETN ; NMI diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm index 6d424e3f..842b54b7 100644 --- a/Source/HBIOS/sio.asm +++ b/Source/HBIOS/sio.asm @@ -59,7 +59,7 @@ SIO_PREINIT0: JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND ; PUSH BC ; SAVE LOOP CONTROL - LD BC,SIO_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,SIO_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL NZ,CIO_ADDENT ; ADD ENTRY IF SIO FOUND, BC:DE POP BC ; RESTORE LOOP CONTROL ; @@ -67,12 +67,20 @@ SIO_PREINIT2: INC C ; NEXT PHYSICAL UNIT DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE ; +#IF (INTMODE == 1) ; ADD IM1 INT CALL LIST ENTRY IF APPROPRIATE LD A,(SIO_DEV) ; GET NEXT DEVICE NUM OR A ; SET FLAGS JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES LD HL,SIO_INT ; GET INT VECTOR CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST +#ENDIF +; +#IF (INTMODE == 2) + ; SETUP SIO INTERRUPT VECTOR IN IVT + LD HL,INT_SIO + LD (HBX_IVT + IVT_SER0),HL +#ENDIF ; SIO_PREINIT3: XOR A ; SIGNAL SUCCESS @@ -215,24 +223,9 @@ SIOB_INT1: OR $FF ; NZ SET TO INDICATE INT HANDLED RET ; AND RETURN ; +; DRIVER FUNCTION TABLE ; -; -SIO_DISPATCH: - ; DISPATCH TO FUNCTION HANDLER - PUSH HL ; SAVE HL FOR NOW - LD A,B ; GET FUNCTION - AND $0F ; ISOLATE LOW NIBBLE - RLCA ; X 2 FOR WORD OFFSET INTO FUNCTION TABLE - LD HL,SIO_FTBL ; START OF FUNC TABLE - CALL ADDHLA ; HL := ADDRESS OF ADDRESS OF FUNCTION - LD A,(HL) ; DEREF HL - INC HL ; ... - LD H,(HL) ; ... - LD L,A ; ... TO GET ADDRESS OF FUNCTION - EX (SP),HL ; RESTORE HL & PUT FUNC ADDRESS -> (SP) - RET ; EFFECTIVELY A JP TO TGT ADDRESS - -SIO_FTBL: +SIO_FNTBL: .DW SIO_IN .DW SIO_OUT .DW SIO_IST @@ -240,6 +233,9 @@ SIO_FTBL: .DW SIO_INITDEV .DW SIO_QUERY .DW SIO_DEVICE +#IF (($ - SIO_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID SIO FUNCTION TABLE ***\n" +#ENDIF ; ; ; @@ -255,7 +251,7 @@ SIO_IN: SIOA_IN: CALL SIOA_IST ; RECEIVED CHAR READY? JR Z,SIOA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - DI ; AVOID COLLISION WITH INT HANDLER + HB_DI ; AVOID COLLISION WITH INT HANDLER LD A,(SIOA_CNT) ; GET COUNT DEC A ; DECREMENT COUNT LD (SIOA_CNT),A ; SAVE SAVE IT @@ -275,14 +271,14 @@ SIOA_IN0: LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER SIOA_IN1: LD (SIOA_TL),HL ; SAVE UPDATED TAIL POINTER - EI ; INTERRUPTS OK AGAIN + HB_EI ; INTERRUPTS OK AGAIN XOR A ; SIGNAL SUCCESS RET ; AND DONE ; SIOB_IN: CALL SIOB_IST ; RECEIVED CHAR READY? JR Z,SIOB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - DI ; AVOID COLLISION WITH INT HANDLER + HB_DI ; AVOID COLLISION WITH INT HANDLER LD A,(SIOB_CNT) ; GET COUNT DEC A ; DECREMENT COUNT LD (SIOB_CNT),A ; SAVE SAVE IT @@ -302,7 +298,7 @@ SIOB_IN0: LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER SIOB_IN1: LD (SIOB_TL),HL ; SAVE UPDATED TAIL POINTER - EI ; INTERRUPTS OK AGAIN + HB_EI ; INTERRUPTS OK AGAIN XOR A ; SIGNAL SUCCESS RET ; AND DONE ; diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index a4c1095f..62827ef0 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -35,11 +35,6 @@ PLT_MK4 .EQU 5 ; MARK IV PLT_UNA .EQU 6 ; UNA BIOS PLT_RC .EQU 7 ; RC2014 ; -; FOUNCTION GROUP FUNCTION COUNTS -; -CIO_FNCNT .EQU 7 -DIO_FNCNT .EQU 12 -; #IF (PLATFORM != PLT_UNA) #INCLUDE "hbios.inc" #ENDIF @@ -173,14 +168,6 @@ SER_115200_8N1 .EQU SER_BAUD115200 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_230400_8N1 .EQU SER_BAUD230400 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_460800_8N1 .EQU SER_BAUD460800 | SER_DATA8 | SER_PARNONE | SER_STOP1 ; -; INTERRUPT TYPE OPTIONS -; -IT_NONE .EQU 0 -IT_SIMH .EQU 1 -IT_Z180 .EQU 2 -IT_CTC .EQU 3 -IT_RC .EQU 4 -; ; INTERRUPT VECTOR TABLE ENTRY OFFSETS (Z180 COMPATIBLE) ; IVT_INT1 .EQU 0 diff --git a/Source/HBIOS/term.asm b/Source/HBIOS/term.asm index 9214924b..40931e47 100644 --- a/Source/HBIOS/term.asm +++ b/Source/HBIOS/term.asm @@ -37,20 +37,20 @@ TERM_ATTACH: LD B,A ; PUT IT IN B PUSH HL ; SAVE VDA INSTANCE DATA PTR ; - ; SETUP EMULATOR MODULE DISPATCH ADDRESS BASED ON DESIRED EMULATION - ; EMULATOR PASSES BACK IT'S DISPATCH ADDRESS IN DE + ; SETUP EMULATOR MODULE FUNC TBL ADDRESS BASED ON DESIRED EMULATION + ; EMULATOR PASSES BACK IT'S FUNC TBL ADDRESS IN DE OR $FF ; PRESET FAILURE #IF (VDAEMU == EMUTYP_TTY) - CALL TTY_INIT ; INIT TTY, DE := TTY_DISPATCH + CALL TTY_INIT ; INIT TTY, DE := TTY_FNTBL #ENDIF #IF (VDAEMU == EMUTYP_ANSI) - CALL ANSI_INIT ; INIT ANSI, DE := ANSI_DISPATCH + CALL ANSI_INIT ; INIT ANSI, DE := ANSI_FNTBL #ENDIF POP HL ; RECOVER VDA INSTANCE DATA PTR RET NZ ; BAIL OUT ON ERROR ; ; ADD OURSELVES TO CIO DISPATCH TABLE - PUSH DE ; COPY EMULATOR DISPATCH ADDRESS + PUSH DE ; COPY EMULATOR FUNC TBL ADDRESS POP BC ; ... TO BC PUSH HL ; COPY VDA INSTANCE DATA PTR POP DE ; ... TO DE @@ -68,7 +68,7 @@ TERM_ATTACH: ; TERMINAL DRIVER PRIVATE DATA ;====================================================================== ; -TERM_DEVCNT .DB 0 ; TERMINAL DEVICE COUNT +TERM_DEVCNT .DB 0 ; TERMINAL DEVICE COUNT ; ;====================================================================== ; EMULATION MODULES diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index e29533a3..49d317b7 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -88,13 +88,13 @@ TMS_INIT1: #ENDIF ; ; ADD OURSELVES TO VDA DISPATCH TABLE - LD BC,TMS_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,TMS_FNTBL ; BC := FUNCTION TABLE ADDRESS LD DE,TMS_IDAT ; DE := TMS INSTANCE DATA PTR CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED ; ; INITIALIZE EMULATION LD C,A ; C := ASSIGNED VIDEO DEVICE NUM - LD DE,TMS_DISPATCH ; DE := DISPATCH ADDRESS + LD DE,TMS_FNTBL ; DE := FUNCTION TABLE ADDRESS LD HL,TMS_IDAT ; HL := TMS INSTANCE DATA PTR CALL TERM_ATTACH ; DO IT ; @@ -102,59 +102,34 @@ TMS_INIT1: RET ; ;====================================================================== -; TMS DRIVER - CHARACTER I/O (CIO) DISPATCHER AND FUNCTIONS +; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== ; -TMS_DISPCIO: - JP PANIC -TMS_CIODISPADR .EQU $ - 2 -; -;====================================================================== -; TMS DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS -;====================================================================== -; -TMS_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JP Z,TMS_VDAINI ; $40 - DEC A - JP Z,TMS_VDAQRY ; $41 - DEC A - JP Z,TMS_VDARES ; $42 - DEC A - JP Z,TMS_VDADEV ; $43 - DEC A - JP Z,TMS_VDASCS ; $44 - DEC A - JP Z,TMS_VDASCP ; $45 - DEC A - JP Z,TMS_VDASAT ; $46 - DEC A - JP Z,TMS_VDASCO ; $47 - DEC A - JP Z,TMS_VDAWRC ; $48 - DEC A - JP Z,TMS_VDAFIL ; $49 - DEC A - JP Z,TMS_VDACPY ; $4A - DEC A - JP Z,TMS_VDASCR ; $4B - DEC A +TMS_FNTBL: + .DW TMS_VDAINI + .DW TMS_VDAQRY + .DW TMS_VDARES + .DW TMS_VDADEV + .DW TMS_VDASCS + .DW TMS_VDASCP + .DW TMS_VDASAT + .DW TMS_VDASCO + .DW TMS_VDAWRC + .DW TMS_VDAFIL + .DW TMS_VDACPY + .DW TMS_VDASCR #IF (PLATFORM == PLT_N8) - JP Z,PPK_STAT ; $4C - DEC A - JP Z,PPK_FLUSH ; $4D - DEC A - JP Z,PPK_READ ; $4E + .DW PPK_STAT + .DW PPK_FLUSH + .DW PPK_READ #ELSE - JP Z,TMS_STAT ; $4C - DEC A - JP Z,TMS_FLUSH ; $4D - DEC A - JP Z,TMS_READ ; $4E + .DW TMS_STAT + .DW TMS_FLUSH + .DW TMS_READ +#ENDIF +#IF (($ - TMS_FNTBL) != (VDA_FNCNT * 2)) + .ECHO "*** INVALID TMS FUNCTION TABLE ***\n" #ENDIF - CALL PANIC TMS_VDAINI: ; RESET VDA diff --git a/Source/HBIOS/tty.asm b/Source/HBIOS/tty.asm index 47eda688..8571af88 100644 --- a/Source/HBIOS/tty.asm +++ b/Source/HBIOS/tty.asm @@ -11,7 +11,7 @@ ; C: CIO UNIT NUMBER OF CALLING VDA DRIVER ; DE: DISPATCH ADDRESS OF CALLING VDA DRIVER ; RETURNS: -; DE: OUR CIO DISPATCH ADDRESS +; DE: OUR CIO FUNC TBL ADDRESS ; TTY_INIT: ; PREVENT ATTEMPTS TO INIT MULTIPLE INSTANCES FOR NOW @@ -24,13 +24,13 @@ TTY_INIT: LD (TTY_DEVNUM),A ; SAVE IT LD A,C ; VDA UNIT NUMBER PASSED IN C LD (TTY_VDAUNIT),A ; SAVE IT - LD (TTY_VDADISPADR),DE ; RECORD VDA DISPATCH ADDRESS + ;LD (TTY_VDADISPADR),DE ; RECORD VDA DISPATCH ADDRESS ; ; INIT/RESET OUR INTERNAL STATE CALL TTY_RESET ; FULL RESET OF EMULATOR INTERNAL STATE RET NZ ; BAIL OUT ON ERROR ; - LD DE,TTY_DISPATCH ; RETURN OUR DISPATCH ADDRESS + LD DE,TTY_FNTBL ; RETURN OUR FUNC TBL ADDRESS XOR A ; SIGNAL SUCCESS RET ; RETURN ; @@ -50,58 +50,55 @@ TTY_RESET: ; ; TTY_VDADISP: - JP PANIC -TTY_VDADISPADR .EQU $ - 2 +; JP PANIC +;TTY_VDADISPADR .EQU $ - 2 + LD A,(TTY_VDAUNIT) + LD C,A + JP VDA_DISPATCH ; +; FUNCTION TABLE ; +TTY_FNTBL: + .DW TTY_IN + .DW TTY_OUT + .DW TTY_IST + .DW TTY_OST + .DW TTY_INITDEV + .DW TTY_QUERY + .DW TTY_DEVICE +#IF (($ - TTY_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID TTY FUNCTION TABLE ***\n" +#ENDIF ; -TTY_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,TTY_CIOIN ; $30 - DEC A - JR Z,TTY_CIOOUT ; $31 - DEC A - JR Z,TTY_CIOIST ; $32 - DEC A - JR Z,TTY_CIOOST ; $33 - DEC A - JR Z,TTY_CIOINIT ; $34 - DEC A - JR Z,TTY_CIOQUERY ; $35 - DEC A - JR Z,TTY_CIODEVICE ; $36 - CALL PANIC ; ; -; -TTY_CIOIN: +TTY_IN: LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ JP TTY_VDADISP ; CHAIN TO VDA DISPATCHER ; ; ; -TTY_CIOOUT: +TTY_OUT: CALL TTY_DOCHAR ; HANDLE THE CHARACTER (EMULATION ENGINE) XOR A ; SIGNAL SUCCESS RET ; ; ; -TTY_CIOIST: +TTY_IST: LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS JP TTY_VDADISP ; CHAIN TO VDA DISPATCHER ; ; ; -TTY_CIOOST: +TTY_OST: XOR A ; ZERO ACCUM INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY RET ; ; ; -TTY_CIOINIT: +TTY_INITDEV: ; RESET THE ATTACHED VDA DEVICE LD B,BF_VDAINI ; FUNC: INIT LD E,-1 ; DO NOT CHANGE VIDEO MODE @@ -112,7 +109,7 @@ TTY_CIOINIT: ; ; ; -TTY_CIOQUERY: +TTY_QUERY: LD DE,$FFFF LD HL,$FFFF XOR A @@ -120,7 +117,7 @@ TTY_CIOQUERY: ; ; ; -TTY_CIODEVICE: +TTY_DEVICE: LD D,CIODEV_TERM ; TYPE IS TERMINAL LD A,(TTY_DEVNUM) ; GET DEVICE NUMBER LD E,A ; PUT IT IN E diff --git a/Source/HBIOS/uart.asm b/Source/HBIOS/uart.asm index ad1dec81..2e8fdb8f 100644 --- a/Source/HBIOS/uart.asm +++ b/Source/HBIOS/uart.asm @@ -85,7 +85,7 @@ UART_PREINIT0: JR Z,UART_PREINIT2 ; SKIP IT IF NOTHING FOUND ; PUSH BC ; SAVE LOOP CONTROL - LD BC,UART_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,UART_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL NZ,CIO_ADDENT ; ADD ENTRY IF UART FOUND, BC:DE POP BC ; RESTORE LOOP CONTROL ; @@ -142,24 +142,9 @@ UART_INIT1: XOR A ; SIGNAL SUCCESS RET ; DONE ; +; DRIVER FUNCTION TABLE ; -; -UART_DISPATCH: - ; DISPATCH TO FUNCTION HANDLER - PUSH HL ; SAVE HL FOR NOW - LD A,B ; GET FUNCTION - AND $0F ; ISOLATE LOW NIBBLE - RLCA ; X 2 FOR WORD OFFSET INTO FUNCTION TABLE - LD HL,UART_FTBL ; START OF FUNC TABLE - CALL ADDHLA ; HL := ADDRESS OF ADDRESS OF FUNCTION - LD A,(HL) ; DEREF HL - INC HL ; ... - LD H,(HL) ; ... - LD L,A ; ... TO GET ADDRESS OF FUNCTION - EX (SP),HL ; RESTORE HL & PUT FUNC ADDRESS -> (SP) - RET ; EFFECTIVELY A JP TO TGT ADDRESS - -UART_FTBL: +UART_FNTBL: .DW UART_IN .DW UART_OUT .DW UART_IST @@ -167,6 +152,9 @@ UART_FTBL: .DW UART_INITDEV .DW UART_QUERY .DW UART_DEVICE +#IF (($ - UART_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID UART FUNCTION TABLE ***\n" +#ENDIF ; ; ; diff --git a/Source/HBIOS/vdu.asm b/Source/HBIOS/vdu.asm index e1498d53..4175dab5 100644 --- a/Source/HBIOS/vdu.asm +++ b/Source/HBIOS/vdu.asm @@ -56,13 +56,13 @@ VDU_INIT1: CALL PPK_INIT ; INITIALIZE KEYBOARD DRIVER ; ; ADD OURSELVES TO VDA DISPATCH TABLE - LD BC,VDU_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,VDU_FNTBL ; BC := FUNCTION TABLE ADDRESS LD DE,VDU_IDAT ; DE := VDU INSTANCE DATA PTR CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED ; ; INITIALIZE EMULATION LD C,A ; ASSIGNED VIDEO UNIT IN C - LD DE,VDU_DISPATCH ; DE := DISPATCH ADDRESS + LD DE,VDU_FNTBL ; DE := FUNCTION TABLE ADDRESS LD HL,VDU_IDAT ; HL := VDU INSTANCE DATA PTR CALL TERM_ATTACH ; DO IT @@ -70,43 +70,28 @@ VDU_INIT1: RET ; ;====================================================================== -; VDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS +; VDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== ; -VDU_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JR Z,VDU_VDAINI ; $40 - DEC A - JR Z,VDU_VDAQRY ; $41 - DEC A - JR Z,VDU_VDARES ; $42 - DEC A - JR Z,VDU_VDADEV ; $43 - DEC A - JR Z,VDU_VDASCS ; $44 - DEC A - JR Z,VDU_VDASCP ; $45 - DEC A - JR Z,VDU_VDASAT ; $46 - DEC A - JR Z,VDU_VDASCO ; $47 - DEC A - JR Z,VDU_VDAWRC ; $48 - DEC A - JR Z,VDU_VDAFIL ; $49 - DEC A - JR Z,VDU_VDACPY ; $4A - DEC A - JR Z,VDU_VDASCR ; $4B - DEC A - JP Z,PPK_STAT ; $4C - DEC A - JP Z,PPK_FLUSH ; $4D - DEC A - JP Z,PPK_READ ; $4E - CALL PANIC +VDU_FNTBL: + .DW VDU_VDAINI + .DW VDU_VDAQRY + .DW VDU_VDARES + .DW VDU_VDADEV + .DW VDU_VDASCS + .DW VDU_VDASCP + .DW VDU_VDASAT + .DW VDU_VDASCO + .DW VDU_VDAWRC + .DW VDU_VDAFIL + .DW VDU_VDACPY + .DW VDU_VDASCR + .DW PPK_STAT + .DW PPK_FLUSH + .DW PPK_READ +#IF (($ - VDU_FNTBL) != (VDA_FNCNT * 2)) + .ECHO "*** INVALID VDU FUNCTION TABLE ***\n" +#ENDIF VDU_VDAINI: ; RESET VDA diff --git a/Source/HBIOS/vga.asm b/Source/HBIOS/vga.asm index 156bc529..420afccc 100644 --- a/Source/HBIOS/vga.asm +++ b/Source/HBIOS/vga.asm @@ -71,15 +71,15 @@ VGA_INIT1: CALL VGA_LOADFONT ; LOAD FONT DATA FROM ROM TO VGA STRORAGE CALL VGA_VDARES CALL KBD_INIT ; INITIALIZE KEYBOARD DRIVER - + ; ADD OURSELVES TO VDA DISPATCH TABLE - LD BC,VGA_DISPATCH ; BC := DISPATCH ADDRESS + LD BC,VGA_FNTBL ; BC := FUNCTION TABLE ADDRESS LD DE,VGA_IDAT ; DE := VGA INSTANCE DATA PTR CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED ; INITIALIZE EMULATION LD C,A ; C := ASSIGNED VIDEO DEVICE NUM - LD DE,VGA_DISPATCH ; DE := DISPATCH ADDRESS + LD DE,VGA_FNTBL ; DE := FUNCTION TABLE ADDRESS LD HL,VGA_IDAT ; HL := VGA INSTANCE DATA PTR CALL TERM_ATTACH ; DO IT @@ -87,43 +87,28 @@ VGA_INIT1: RET ; ;====================================================================== -; VGA DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS +; VGA DRIVER - VIDEO DISPLAY ADAPTER (VDA) FUNCTIONS ;====================================================================== ; -VGA_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JP Z,VGA_VDAINI ; $40 - DEC A - JP Z,VGA_VDAQRY ; $41 - DEC A - JP Z,VGA_VDARES ; $42 - DEC A - JP Z,VGA_VDADEV ; $43 - DEC A - JP Z,VGA_VDASCS ; $44 - DEC A - JP Z,VGA_VDASCP ; $45 - DEC A - JP Z,VGA_VDASAT ; $46 - DEC A - JP Z,VGA_VDASCO ; $47 - DEC A - JP Z,VGA_VDAWRC ; $48 - DEC A - JP Z,VGA_VDAFIL ; $49 - DEC A - JP Z,VGA_VDACPY ; $4A - DEC A - JP Z,VGA_VDASCR ; $4B - DEC A - JP Z,KBD_STAT ; $4C - DEC A - JP Z,KBD_FLUSH ; $4D - DEC A - JP Z,KBD_READ ; $4E - CALL PANIC +VGA_FNTBL: + .DW VGA_VDAINI + .DW VGA_VDAQRY + .DW VGA_VDARES + .DW VGA_VDADEV + .DW VGA_VDASCS + .DW VGA_VDASCP + .DW VGA_VDASAT + .DW VGA_VDASCO + .DW VGA_VDAWRC + .DW VGA_VDAFIL + .DW VGA_VDACPY + .DW VGA_VDASCR + .DW KBD_STAT + .DW KBD_FLUSH + .DW KBD_READ +#IF (($ - VGA_FNTBL) != (VDA_FNCNT * 2)) + .ECHO "*** INVALID VGA FUNCTION TABLE ***\n" +#ENDIF VGA_VDAINI: ; RESET VDA diff --git a/Source/Images/hd0/s1/u0/pmarc.com b/Source/Images/hd0/s1/u0/pmarc.com new file mode 100644 index 00000000..59bd3ef3 Binary files /dev/null and b/Source/Images/hd0/s1/u0/pmarc.com differ diff --git a/Source/Images/hd0/s1/u0/pmext.com b/Source/Images/hd0/s1/u0/pmext.com new file mode 100644 index 00000000..d3a51ca3 Binary files /dev/null and b/Source/Images/hd0/s1/u0/pmext.com differ