diff --git a/Doc/ROM Applications.pdf b/Doc/ROM Applications.pdf index cfd947b6..cc0b4ef0 100644 Binary files a/Doc/ROM Applications.pdf and b/Doc/ROM Applications.pdf differ diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index 370de57c..7ada70cb 100644 Binary files a/Doc/RomWBW Applications.pdf and b/Doc/RomWBW Applications.pdf differ diff --git a/Doc/RomWBW Architecture.pdf b/Doc/RomWBW Architecture.pdf index 6fb56ef5..33026681 100644 Binary files a/Doc/RomWBW Architecture.pdf and b/Doc/RomWBW Architecture.pdf differ diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf index e1e9ad78..e41f51cb 100644 Binary files a/Doc/RomWBW Disk Catalog.pdf and b/Doc/RomWBW Disk Catalog.pdf differ diff --git a/Doc/RomWBW Getting Started.pdf b/Doc/RomWBW Getting Started.pdf index 5e4bee5f..323725fa 100644 Binary files a/Doc/RomWBW Getting Started.pdf and b/Doc/RomWBW Getting Started.pdf differ diff --git a/ReadMe.md b/ReadMe.md index 6988a610..18e8c3a8 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ ## Z80/Z180 System Software Version 3.1 Pre-release -13 Jan 2023 +15 Jan 2023 Wayne Warthen @@ -881,8 +881,8 @@ under RomWBW. Unlike the OSes above, p-System uses it’s own unique filesystem and is not interoperable with other OSes. It was derived from the p-System Adaptable Z80 System. Unlike some other -distributions, this implements a native p-System Z80 BIOS, it does not -rely on a CP/M BIOS layer. +distributions, this implements a native p-System Z80 Extended BIOS, it +does not rely on a CP/M BIOS layer. The p-System is provided on a hard disk image file called psys.img. This must be copied to it’s own dedicated hard disk media (CF Card, SD Card, diff --git a/ReadMe.txt b/ReadMe.txt index d1ed1570..1307d7e0 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,6 +1,6 @@ RomWBW Getting Started Wayne Warthen (mailto:wwarthen@gmail.com) -13 Jan 2023 +15 Jan 2023 @@ -17,7 +17,7 @@ RomWBW Z80/Z180 System Software Version 3.1 Pre-release -13 Jan 2023 +15 Jan 2023 Wayne Warthen wwarthen@gmail.com @@ -953,8 +953,8 @@ under RomWBW. Unlike the OSes above, p-System uses it’s own unique filesystem and is not interoperable with other OSes. It was derived from the p-System Adaptable Z80 System. Unlike some other -distributions, this implements a native p-System Z80 BIOS, it does not -rely on a CP/M BIOS layer. +distributions, this implements a native p-System Z80 Extended BIOS, it +does not rely on a CP/M BIOS layer. The p-System is provided on a hard disk image file called psys.img. This must be copied to it’s own dedicated hard disk media (CF Card, SD Card, diff --git a/Source/Doc/GettingStarted.md b/Source/Doc/GettingStarted.md index d492f315..ee467a2f 100644 --- a/Source/Doc/GettingStarted.md +++ b/Source/Doc/GettingStarted.md @@ -907,7 +907,7 @@ own unique filesystem and is not interoperable with other OSes. It was derived from the p-System Adaptable Z80 System. Unlike some other distributions, this implements a native p-System -Z80 BIOS, it does not rely on a CP/M BIOS layer. +Z80 Extended BIOS, it does not rely on a CP/M BIOS layer. The p-System is provided on a hard disk image file called psys.img. This must be copied to it's own dedicated hard diff --git a/Source/pSys/Build.cmd b/Source/pSys/Build.cmd index f0c914c6..73fdd085 100644 --- a/Source/pSys/Build.cmd +++ b/Source/pSys/Build.cmd @@ -8,9 +8,9 @@ set PATH=%TOOLS%\tasm32;%PATH% set TASMTABS=%TOOLS%\tasm32 echo. -echo Building p-System Loader for RomWBW... +echo Building p-System BIOS Tester Loader for RomWBW... echo. -tasm -t80 -g3 loader.asm loader.bin loader.lst || exit /b +tasm -t80 -g3 -dTESTBIOS loader.asm testldr.bin testldr.lst || exit /b if errorlevel 1 goto :eof echo. @@ -19,19 +19,37 @@ echo. tasm -t80 -g3 bios.asm bios.bin bios.lst || exit /b if errorlevel 1 goto :eof -::echo. -::echo Creating p-System BIOS Tester boot image -::echo. -::copy /b loader.bin + bios.bin + biostest.dat psys.bin +echo. +echo Building p-System Loader for RomWBW... +echo. +tasm -t80 -g3 loader.asm loader.bin loader.lst || exit /b +if errorlevel 1 goto :eof + +echo. +echo Generating p-System BIOS Tester filler... +echo. +tasm -t80 -g3 fill.asm fill.bin fill.lst || exit /b +if errorlevel 1 goto :eof + +echo. +echo Generating p-System Boot Track filler... +echo. +tasm -t80 -g3 -dTESTBIOS fill.asm testfill.bin testfill.lst || exit /b +if errorlevel 1 goto :eof + +echo. +echo Creating p-System BIOS Tester boot image +echo. +copy /b ..\Images\hd1024_prefix.dat + testldr.bin + bios.bin + biostest.dat + testfill.bin psystest.img || exit /b echo. echo Generating p-System Boot Track... echo. -copy /b loader.bin + bios.bin + boot.dat + fill.dat trk0.bin || exit /b +copy /b loader.bin + bios.bin + boot.dat + fill.bin trk0.bin || exit /b echo. echo Generating p-System Disk Image... echo. -copy /b trk0.bin + psys.vol + trk0.bin + blank.vol psys.img || exit /b +copy /b ..\Images\hd1024_prefix.dat + trk0.bin + psys.vol + trk0.bin + blank.vol psys.img || exit /b copy psys.img ..\..\Binary || exit /b \ No newline at end of file diff --git a/Source/pSys/Makefile b/Source/pSys/Makefile index 427470af..398eef2d 100644 --- a/Source/pSys/Makefile +++ b/Source/pSys/Makefile @@ -1,11 +1,22 @@ -OBJECTS = psys.img +OBJECTS = psys.img psystest.img TOOLS = ../../Tools DEST = ../../Binary OTHERS = *.bin *.lst *.img +NOCOPY = psystest.img include $(TOOLS)/Makefile.inc -trk0.bin: loader.bin bios.bin boot.dat fill.dat - cat loader.bin bios.bin boot.dat fill.dat > trk0.bin +trk0.bin: loader.bin bios.bin boot.dat fill.bin + cat $+ >$@ -psys.img: trk0.bin psys.vol blank.vol - cat trk0.bin psys.vol trk0.bin blank.vol > psys.img +psys.img: ../Images/hd1024_prefix.dat trk0.bin psys.vol trk0.bin blank.vol + cat $+ >$@ + +testldr.bin: loader.asm + $(TASM) -dTESTBIOS $< $@ testldr.lst + +testfill.bin: fill.asm + $(TASM) -dTESTBIOS $< $@ testfill.lst + + +psystest.img: ../Images/hd1024_prefix.dat testldr.bin bios.bin biostest.dat testfill.bin + cat $+ >$@ diff --git a/Source/pSys/ReadMe.txt b/Source/pSys/ReadMe.txt index 04d335a0..6c12b3af 100644 --- a/Source/pSys/ReadMe.txt +++ b/Source/pSys/ReadMe.txt @@ -1,8 +1,8 @@ This directory contains a port of p-System IV.0 for RomWBW. -It was derived from the p-System Adaptable Z80 System. Unlike -some other distributions, this implements a native p-System -Z80 BIOS, it does not use a CP/M BIOS layer. +It was derived from the p-System Adaptable Z80 System. Unlike some +other distributions, this implements a native p-System Z80 Extended +BIOS, it does not use a CP/M BIOS layer. Files: @@ -12,49 +12,44 @@ biostest.dat binary image of SBIOSTESTER boot.dat binary image of p-System bootstrap psys.vol first (boot) slice, all p-System dist files blank.vol a generic blank p-System volume -fill.dat used to complete the track 0 build (see below) +fill.asm used to complete the track 0 build (see below) Notes: -This adatation runs on a single RomWBWW HBIOS hard disk -type device (CF Cart, SD Card, IDE drive, etc.). The -image built (psys.img) should be copied to your disk media -start at the first sector. You can then boot by selecting -the corresponding disk device unit number from the RomWBW -boot loader prompt. The p-System disk image (psys.img) is -entirely different from the RomWBW CP/M-style disk images. - -The boot device hard disk is broken up into 6 logical -p-System volumes. These are referred to as p-System -slices. A single RomWBW disk device can contain either -CP/M-style slices or p-System slices, but not both. -Each p-System slices is exactly 8 MB and support for +This adatation runs on a single RomWBWW HBIOS hard disk type device (CF +Cart, SD Card, IDE drive, etc.). The image built (psys.img) should be +copied to your disk media start at the first sector. You can then boot +by selecting the corresponding disk device unit number from the RomWBW +boot loader prompt. The p-System disk image (psys.img) is entirely +different from the RomWBW CP/M-style disk images. + +The boot device hard disk is broken up into 6 logical p-System +volumes. These are referred to as p-System slices. A single RomWBW +disk device can contain either CP/M-style slices or p-System slices, +but not both. Each p-System slices is exactly 8 MB and support for exactly 6 slices is provided. -The first track of each volume contains all of the code -required to boot the p-System. However, the assignment -of the volumes is always in the order that the slices -appear physically on the hard disk device. Normally, -you would just boot to slice 0 from the RomWBW Boot -Loader. +The first track of each volume contains all of the code required to +boot the p-System. However, the assignment of the volumes is always in +the order that the slices appear physically on the hard disk device. +Normally, you would just boot to slice 0 from the RomWBW Boot Loader. The first track contains the following: - 4 sector p-System primary loader for RomWBW HBIOS - - 1 sector p-System BIOS for RomWBW HBIOS + - 1.5 sector p-System BIOS for RomWBW HBIOS - 4 sector p-System bootstrap - - 7 sector filler to complete a full track + - 6.5 sector filler to complete a full track -The p-System bootstrap is a binary image provided in the -p-System distribution. The loader and the BIOS are -custom for RomWBW and the source is provided here. +The p-System bootstrap is a binary image provided in the p-System +distribution. The loader and the BIOS are custom for RomWBW and the +source is provided here. -The layout of the first track does not conform exactly to -the recommended p-System layout. The recommended layout -is not possible because it conflicts with the RomWBW -definition for a boot track. However, the changes are -simply slilghtly different sector assignments for the -different boot componets -- the general boot sequence -and mechanism for the p-System is completely standard. +The layout of the first track does not conform exactly to the +recommended p-System layout. The recommended layout is not possible +because it conflicts with the RomWBW definition for a boot track. +However, the changes are only slightly different sector assignments for +the different boot componets -- the general boot sequence and mechanism +for the p-System is completely standard. The logical disk geometry used by this p-System adaptation is: @@ -62,39 +57,38 @@ adaptation is: - 16 sectors per track - 192 tracks per disk -This layout does not occupy the full 8MB slice size -allocated. This is to allow for future expansion of -the filesystems. - -The p-System distribution includes a BIOS tester that -is provided as a binary image. This tester was used -to test the BIOS code in this adaptation. Note that -the tester fails for the BIOS as is. After a lot of -code tracing, a definite bug was identified in the -tester that exists for 512 byte sectors (which are -supported). When the BIOS is modified to use 128 or -256 byte sectors, the tester completes perfectly. -Significant use of the BIOS shows there are no issues -for a normal running system with 512 byte sectors. - -The boot disk provided here was constructed by simply -copying all of the content from the p-System distribution -disks onto the boot disk. SYSTEM.MISCINFO was updated -for an ANSI terminal. The GOTOXY routine in -SYSTEM.PASCAL was also updated for an ANSI terminal. -Note that the BIOS conwrit routine is hacked to add -a '[' to any output escape character. This is needed -because p-System has limited terminal escape sequence -handling configuration. - -At this time, there is no straightforward way to move -files in and out of the p-System volumes. There are -ways to do this, but they are complicated. Please -contact me if you are interested. +This layout does not occupy the full 8MB slice size allocated. This is +to allow for future expansion of the filesystems. + +The p-System distribution includes a BIOS tester that is provided as a +binary image. This tester was used to test the BIOS code in this +adaptation. It turns out that this code has a blatant error that +causes it to fail for 512 byte sector sizes (which are allowed). +To resolve this, biostest.dat was disassembled and patched to correct +the error. The original version is retained as biostest.old. + +The boot disk provided here was constructed by simply copying all of +the content from the p-System distribution disks onto the boot disk. +SYSTEM.MISCINFO was updated for an ANSI terminal. The GOTOXY routine +in SYSTEM.PASCAL was also updated for an ANSI terminal. Note that the +BIOS conwrit routine is hacked to add a '[' to any output escape +character. This is needed because p-System has a very limited terminal +escape sequence handling configuration. The debugger code as added to +SYSTEM.PASCAL to enable the debug function. SYSTEM.INTERP was modified +to enable the extended BIOS functions. + +The build/makefile creates the psys disk image (psys.img) by adding +concatentating psys.vol and blank.vol (after adding track 0 contents to +each). psys.vol and blank.vol are recognized by CiderPress and +CiderPress can be used to add/remove files from these volumes. +However, there is currently no straightforward way to extract the +volumes from the disk image. If you are good with a binary disk +editor, you can do it that way. Please contact me if you are +interested in pursuing that. There is currently no support for floppy drives. Wayne Warthen wwarthen@gmail.com -3:13 PM Thursday, January 12, 2023 \ No newline at end of file +5:42 PM Sunday, January 15, 2023 \ No newline at end of file diff --git a/Source/pSys/bios.asm b/Source/pSys/bios.asm index f7107b69..9f1a3ae0 100644 --- a/Source/pSys/bios.asm +++ b/Source/pSys/bios.asm @@ -1,52 +1,56 @@ ; -;----------------------------------------------------------------------- +;======================================================================= ; p-System BIOS for RomWBW HBIOS -; -;----------------------------------------------------------------------- +;======================================================================= ; ; 3:46 PM 1/13/2023 - WBW - Initial release +; 5:29 PM 1/15/2023 - WBW - Implemeted extended BIOS functions +; 10:34 AM 1/16/2023 - WBW - Moved slices into partition ; ; TODO: ; -; - Assign the HBIOS console device to the p-System console instead -; of just using a hard-coded reference to Serial Unit 0. +; NOTES: +; - The partition type ID used is the same as the CP/M partition +; type ID. Might make sense to create a new partition ID which +; could allow p-System to co-exist with CP/M on a disk image. This +; would require changes to the RomWBW boot loader as well. ; -; - Implement Extended BIOS. +; - MBR is borrowed from RomWBW CP/M layout, so the partition size +; is 64 8MB slices. p-System only uses 6 slices. Might be better +; to create a custom MBR with an appropriate size for p-System +; partition. ; +; - The sysinit routine does a lot of work that just sets up a few +; variables for later use. This work could be moved into the +; p-System loader to reduce the size of this BIOS. Since the BIOS +; is only 768 bytes at this point, I have not bothered with it. +; #include "../ver.inc" -; + #include "psys.inc" -; + +#include "psys_ior.inc" + #include "../HBIOS/hbios.inc" -; -; IORESULT values -; -ior_ok .equ 0 ; No error -ior_badblk .equ 1 ; Bad block, CRC error (parity) -ior_baddev .equ 2 ; Bad device number -ior_badio .equ 3 ; Illegal I/O request -ior_timout .equ 4 ; Data-com timeout -ior_offlin .equ 5 ; Volume is no longer on-line -ior_nofile .equ 6 ; File is no longer in directory -ior_filnamerr .equ 7 ; Illegal file name -ior_full .equ 8 ; No room; insufficient space on disk -ior_novol .equ 9 ; No such volume on-line -ior_notfnd .equ 10 ; No such file name in directory -ior_dupfil .equ 11 ; Duplicate file -ior_notclos .equ 12 ; Not closed: attempt to open an open file -ior_notopen .equ 13 ; Not open: attempt to access a closed file -ior_badfmt .equ 14 ; Bad format: error reading real or integer -ior_bufovr .equ 15 ; Ring buffer overflow -ior_diskwp .equ 16 ; Write attempt to protected disk -ior_blknumerr .equ 17 ; Illegal block number -ior_bufadrerr .equ 18 ; Illegal buffer address -ior_badsiz .equ 19 ; Bad text file size -; -; -; + +;----------------------------------------------------------------------- +; Local constants +;----------------------------------------------------------------------- + +; We need to read and buffer a single sector (MBR) at initialization. +; It looks like the area just above the loader is the safest place. + +dskbuf .equ loader_loc + loader_size + + + +;----------------------------------------------------------------------- +; BIOS Jump Table +;----------------------------------------------------------------------- + .org bios_loc -; + ; Simple BIOS vectors jp sysinit ; 0: Initialize machine jp syshalt ; 1: Exit UCSD Pascal @@ -63,309 +67,511 @@ ior_badsiz .equ 19 ; Bad text file size jp dskinit ; 12: Reset disk jp dskstrt ; 13: Activate disk jp dskstop ; 14: De-activate disk -; + ; Extended BIOS vectors - jp panic ; 15: Extended BIOS vector - jp panic ; 16: Extended BIOS vector - jp panic ; 17: Extended BIOS vector - jp panic ; 18: Extended BIOS vector - jp panic ; 19: Extended BIOS vector - jp panic ; 20: Extended BIOS vector - jp panic ; 21: Extended BIOS vector - jp panic ; 22: Extended BIOS vector - jp panic ; 23: Extended BIOS vector - jp panic ; 24: Extended BIOS vector - jp panic ; 25: Extended BIOS vector - jp panic ; 26: Extended BIOS vector - jp panic ; 27: Extended BIOS vector -; -; -; -sysinit: - ;ld a,0 - ;jp panic - - ld hl,str_banner - call prtstr - call conread + jp prninit ; 15: Printer initialize + jp prnstat ; 16: Printer status + jp prnread ; 17: Printer read + jp prnwrit ; 18: Printer write + jp reminit ; 19: Remote initialize + jp remstat ; 20: Remote status + jp remread ; 21: Remote read + jp remwrit ; 22: Remote write + jp usrinit ; 23: User devices initialize + jp usrstat ; 24: User devices status + jp usrread ; 25: User devices read + jp usrwrit ; 26: User devices write + jp clkread ; 27: System clock read + +;----------------------------------------------------------------------- +; Simple BIOS routines +;----------------------------------------------------------------------- + + +sysinit: ; 0: Initialize machine + ; Get critical HBIOS bank ids for use later + ld b,BF_SYSGET ; HBIOS SysGet function + ld c,BF_SYSGET_BNKINFO ; BankInfo sub-function + rst 08 ; do it, D=BIOS, E=USER + ld (hb_bnks),de ; save bank info + ; Get boot disk to use for all subsequent disk I/O ld b,BF_SYSGET ; HBIOS SysGet function ld c,BF_SYSGET_BOOTINFO ; BootInfo sub-function rst 08 ; do it, boot disk device unit in ld a,d ; boot unit id returned in D ld (hb_dev),a ; save for disk I/O + + ; Get the count of serial (CIO) HBIOS devices in system + ld b,BF_SYSGET ; HBIOS SysGet function + ld c,BF_SYSGET_CIOCNT ; CIO Count sub-function + rst 08 ; do it, count in E + push de ; save it + + ; Get current HBIOS console unit and assign to pSys console + ld b,BF_SYSPEEK ; HBIOS Peek Function + ld a,(hb_bios) ; HBIOS bank id + ld d,a ; ... goes in D + ld hl,$112 ; offset $112 is current console device + rst 08 ; call HBIOS, value returned in E + ld a,e ; move to A + ld hl,hb_con ; use HL to point to hb_con + ld (hl),a ; save as console device + + ; Assign additional HBIOS serial devices as pSys remote and printer + pop bc ; recover CIO count, now in C + ld a,0 ; assume remote on HB unit 0 + cp (hl) ; conflict? + jr nz,sysinit1 ; if no conflict, continue + inc a ; else increment to next unit +sysinit1: + cp c ; check for over max serial count + jr nc,sysinit3 ; if exceeded, we are done + ld (hb_rem),a ; assign remote device + inc a ; bump to next dev for printer + cp (hl) ; conflict? + jr nz,sysinit2 ; if no conflict, continue + inc a ; else increment to next unit +sysinit2: + cp c ; check for over max serial count + jr nc,sysinit3 ; if exceeded, we are done + ld (hb_prn),a ; assign printer device +sysinit3: + + ; Announce BIOS + ld hl,str_banner ; load version banner + call prtstr ; and display it + ;call conread ; wait for user + + ; The p-System slices live within a disk partition. So, now we + ; read the MBR, look for our partition ID, extract the + ; corresponding LBA offset and save it for subsequent disk I/O. + + ; Read MBR. The MBR lives in the first sector of the hard + ; disk. At this point paroff, curdisk, curtrak, and cursect + ; are all zero. So, we just set the disk buffer and make a + ; disk I/O call which results in reading the first (MBR) + ; sector. + ld bc,dskbuf ; load disk buf adr + ld (curbufr),bc ; save it + call dskread ; read first sector of phy disk + jp nz,parterr ; abort on error + + ; Check signature + ld hl,(dskbuf+$1FE) ; get signature + ld a,l ; first byte + cp $55 ; should be $55 + jp nz,parterr ; if not, no part table + ld a,h ; second byte + cp $AA ; should be $AA + jp nz,parterr ; if not, no part table + + ; Search part table for entry (type 0x2E) + ld b,4 ; four entries in part table + ld hl,dskbuf+$1BE+4 ; offset of first part type +sysinit4: + ld a,(hl) ; get part type + cp $2E ; CP/M partition? + jr z,sysinit5 ; cool, grab the LBA offset + ld de,16 ; part table entry size + add hl,de ; bump to next part type + djnz sysinit4 ; loop thru table + jp parterr ; too bad, no CP/M partition +sysinit5: + ; Capture the starting LBA of the partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,paroff ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + +sysinit6: - ; sysinit is being called twice during startup. Once from - ; the bootstrap and then from the interpreter. So, we + ; Vector sysinit is being called twice during startup. Once + ; from the bootstrap and then from the interpreter. So, we ; remap the vector here to avoid doing the above stuff ; multiple times. - ld hl,sysinit1 ; re-vector to sysinit1 + ld hl,sysinitz ; re-vector to sysinitz ld (bios_loc+1),hl ; update the jump table -sysinit1: - xor a ; signal success - ret ; done - -syshalt: - ;ld a,1 - ;jp panic +sysinitz: + ret ; done + xor a ; signal success +syshalt: ; 1: Exit UCSD Pascal ; The syshalt vector does not seem be to invoked when ; selecting the Halt option from the p-System menu. ; I have no idea why. - ld b,BF_SYSRESET ; HBIOS reset function + ld b,BF_SYSRESET ; HBIOS reset function ld c,BF_SYSRES_WARM ; warm reset is fine - rst 08 ; do it + rst 08 ; do it - ; we should never get here - di ; interrupts off - halt ; ... and die + ; We should never get here. + di ; interrupts off + halt ; ... and die -coninit: - ;ld a,2 - ;jp panic - - xor a ; signal success - ret ; done - -constat: - ;ld a,3 - ;jp panic - - ld b,BF_CIOIST ; serial port status function - ld c,0 ; port 0 - rst 08 ; call HBIOS - ld c,0 ; assume no chars pendin - jr z,constat1 ; if zero, no chars waiting - ld c,$FF ; signal char(s) pending -constat1: - xor a ; signal success - ret ; done - -conread: - ;ld a,4 - ;jp panic - - ld b,BF_CIOIN ; serial port read function - ld c,0 ; port 0 - rst 08 ; call HBIOS - ld c,e ; char to C - xor a ; signal success - ret ; done - -conwrit: - ;ld a,5 - ;jp panic +coninit: ; 2: Console initialize + ld a,(hb_con) ; initialize console unit + jp serinit ; do it + +constat: ; 3: Console status + ld a,(hb_con) ; status of console unit + jp serstat ; do it - ld a,c - cp 27 ; escape? - jr nz,conwrit1 ; if not, handle normally - call conwrit1 ; else, send escape - ld c,'[' ; ... followed by '[' for ANSI -conwrit1: - ld e,c ; char to write to E - ld b,BF_CIOOUT ; serial port write function - ld c,0 ; port 0 - rst 08 ; call HBIOS - xor a ; signal success - ret ; done - -setdisk: - ;ld a,6 - ;jp panic - - ld a,c ; disk number to A - ld (curdisk),a ; save for later - xor a ; signal success - ret ; done - -settrak: - ;ld a,7 - ;jp panic - - ld a,c ; track number to A - ld (curtrak),a ; save for later - xor a ; signal success - ret ; done - -setsect: - ;ld a,8 - ;jp panic +conread: ; 4: Console input + ld a,(hb_con) ; read from console unit + jp serread ; do it - ld a,c ; sector number to A - dec a ; from 1 indexed to 0 indexed - ld (cursect),a ; save for later - xor a ; signal success - ret - -setbufr: - ;ld a,9 - ;jp panic +conwrit: ; 5: Console output + ld a,c + cp 27 ; escape? + ld a,(hb_con) ; write to console unit + jp nz,serwrit ; if not, handle normally + call serwrit ; else, send escape + ld c,'[' ; ... followed by '[' for ANSI + ld a,(hb_con) ; write to console unit + jp serwrit ; do it - ld (curbufr),bc ; save buf adr for later - xor a ; signal success - ret ; done - -dskread: - ;ld a,10 - ;jp panic - - ;ld a,(curdisk) - ;cp 0 - ;jr nz,dskinit1 +setdisk: ; 6: Set disk number + ld a,c ; disk number to A + ld (curdisk),a ; save for later + + ; Each p-System disk lives in a slice. Additionally, + ; the start of the slices is determined by the hard + ; disk partition table. To avoid computing the p-System + ; disk offset on every I/O call, below we pre-compute + ; the physical HBIOS disk LBA offset for the slice of the + ; p-System disk being selected here. + ld hl,(paroff) ; initialize DE:HL + ld de,(paroff+2) ; ... to start of partition + or a ; use A as loop ctr, check for zero + jr z,setdisk2 ; if 0, no slice offset needed +setdisk1: + ld bc,(sps) ; get low word of sps + add hl,bc ; add low words + ex de,hl ; swap high word into HL + ld bc,(sps+2) ; get high word of sps + adc hl,bc ; add high words (w/ carry) + ex de,hl ; swap back to get DE:HL + dec a ; dec loop ctr + jr nz,setdisk1 ; rinse and repeat +setdisk2: + ld (curoff),hl ; save low word + ld (curoff+2),de ; save high word - call chkdisk - ret nz - - call seek - ret nz - - ld b,BF_DIOREAD ; HBIOS disk read function - ld a,(hb_dev) ; HBIOS disk unit - ld c,a ; ... goes in C - ld a,(HB_CURBNK) ; get current memory bank - ld d,a ; use as target bank for transfer - ld e,1 ; read 1 sector - ld hl,(curbufr) ; disk read buffer adr - rst 08 ; do it - ret z ; return if good read - ld a,ior_badblk ; else i/o error - ret ; done + xor a ; signal success + ret ; done + +settrak: ; 7: Set track number + ld a,c ; track number to A + ld (curtrak),a ; save for later + xor a ; signal success + ret ; done -dskwrit: - ;ld a,11 - ;jp panic +setsect: ; 8: Set sector number + ld a,c ; sector number to A + dec a ; from 1 indexed to 0 indexed + ld (cursect),a ; save for later + xor a ; signal success + ret + +setbufr: ; 9: Set buffer address + ld (curbufr),bc ; save buf adr for later + xor a ; signal success + ret ; done +dskread: ; 10: Read sector from disk call chkdisk ret nz call seek ret nz - ld b,BF_DIOWRITE ; HBIOS disk read function - ld a,(hb_dev) ; HBIOS disk unit - ld c,a ; ... goes in C - ld a,(HB_CURBNK) ; get current memory bank - ld d,a ; use as target bank for transfer - ld e,1 ; read 1 sector - ld hl,(curbufr) ; disk read buffer adr - rst 08 ; do it - ret z ; return if good read - ld a,ior_badblk ; else i/o error - ret ; done - -dskinit: - ;ld a,12 - ;jp panic + ld b,BF_DIOREAD ; HBIOS disk read function + ld a,(hb_dev) ; HBIOS disk unit + ld c,a ; ... goes in C + ld a,(HB_CURBNK) ; get current memory bank + ld d,a ; use as target bank for transfer + ld e,1 ; read 1 sector + ld hl,(curbufr) ; disk read buffer adr + rst 08 ; do it + ret z ; return if good read + ld a,ior_badblk ; else i/o error + ret ; done + +dskwrit: ; 11: Write sector to disk + call chkdisk + ret nz - call chkdisk + call seek ret nz + + ld b,BF_DIOWRITE ; HBIOS disk read function + ld a,(hb_dev) ; HBIOS disk unit + ld c,a ; ... goes in C + ld a,(HB_CURBNK) ; get current memory bank + ld d,a ; use as target bank for transfer + ld e,1 ; read 1 sector + ld hl,(curbufr) ; disk read buffer adr + rst 08 ; do it + ret z ; return if good read + ld a,ior_badblk ; else i/o error + ret ; done + +dskinit: ; 12: Reset disk + call chkdisk + ret nz + + xor a ; signal success + ret ; done + +dskstrt: ; 13: Activate disk + xor a ; signal success + ret ; done + +dskstop: ; 14: De-activate disk + xor a ; signal success + ret ; done + +;----------------------------------------------------------------------- +; Extended BIOS routines +;----------------------------------------------------------------------- + +prninit: ; 15: Printer initialize + ld a,(hb_prn) ; initialize printer unit + jp serinit ; do it + +prnstat: ; 16: Printer status + ld a,(hb_prn) ; status of printer unit + jp serstat ; do it - xor a ; signal success - ret ; done +prnread: ; 17: Printer read + ld a,(hb_prn) ; read from printer unit + jp serread ; do it -dskstrt: - ;ld a,13 - ;jp panic +prnwrit: ; 18: Printer write + ld a,(hb_prn) ; write to printer unit + jp serwrit ; do it - xor a ; signal success - ret ; done +reminit: ; 19: Remote initialize + ld a,(hb_rem) ; initialize remote unit + jp serinit ; do it -dskstop: - ;ld a,14 - ;jp panic +remstat: ; 20: Remote status + ld a,(hb_rem) ; status of remote unit + jp serstat ; do it - xor a ; signal success - ret ; done +remread: ; 21: Remote read + ld a,(hb_rem) ; read from remote unit + jp serread ; do it + +remwrit: ; 22: Remote write + ld a,(hb_rem) ; write to remote unit + jp serwrit ; do it + +usrinit: ; 23: User devices initialize + ld a,9 ; offline status + ret + +usrstat: ; 24: User devices status + pop hl ; return address + pop de ; discard input/output toggle + pop de ; discard ptr to status rec + pop de ; discard device number + ld a,9 ; offline status + jp (hl) ; return + +usrread: ; 25: User devices read +usrwrit: ; 26: User devices write + pop hl ; return address + pop de ; extra parameter 2 + pop de ; extra parameter 1 + pop de ; pointer to buffer + pop de ; device number + pop de ; extra parameter 5 + ld a,9 ; offline status + jp (hl) ; return + +clkread: ; 27: System clock read + ld b,BF_SYSGET ; HBIOS SysGet function + ld c,BF_SYSGET_TIMER ; Timer sub-function + rst 08 ; do it, ticks ret in DE:HL + ex de,hl ; swap for pSys + xor a ; signal success + ret ; done + + + +;----------------------------------------------------------------------- +; Support routines +;----------------------------------------------------------------------- + +serinit: + ; Initialize HBIOS serial port identified in reg A + cp $FF ; do we have desired port? + jr z,nodev ; handle it if so + xor a ; signal success + ret ; done + +serstat: + ; Check status of HBIOS serial port identified in reg A + cp $FF ; do we have desired port? + jr z,nodev ; handle it if so + ld b,BF_CIOIST ; serial port status function + ld c,a ; HBIOS serial port + rst 08 ; call HBIOS + ld c,0 ; assume no chars pendin + jr z,serstat1 ; if zero, no chars waiting + ld c,$FF ; signal char(s) pending +serstat1: + xor a ; signal success + ret ; done + +serread: + ; Read one byte from HBIOS serial port identified in reg A + cp $FF ; do we have desired port? + jr z,nodev ; handle it if so + ld b,BF_CIOIN ; serial port read function + ld c,a ; HBIOS serial port + rst 08 ; call HBIOS + ld c,e ; char to C + xor a ; signal success + ret ; done + +serwrit: + ; Write one byte to HBIOS serial port identified in reg A + cp $FF ; do we have desired port? + jr z,nodev ; handle it if so + ld e,c ; char to write to E + ld b,BF_CIOOUT ; serial port write function + ld c,a ; HBIOS serial port + rst 08 ; call HBIOS + xor a ; signal success + ret ; done + +nodev: + ld a,9 ; signal volume offline + ret ; and done chkdisk: ; Validate that curdisk is <= max supported - ld a,(curdisk) ; get current disk - cp disks ; compare to disk count - jr nc,chkdisk1 ; if too high, go to err - xor a ; signal success - ret ; done -chkdisk1: - ld a,ior_novol ; signal not online - or a - ret + ld a,(curdisk) ; get current disk + cp disks ; compare to disk count + jr nc,chkdisk1 ; if too high, go to err + xor a ; signal success + ret ; done +chkdisk1: + ld a,ior_novol ; signal not online + or a ; set flags + ret ; done seek: - ; A single physical HBIOS disk device will contain p-System - ; volume slices. Each slice will be 8MB. Start by computing - ; a track offset using the p-System disk number as an - ; index. = 8MB * - ; A track contains 0x20000 bytes: - ; 512 (bytes per sec) * 16 (sec per trk) * 16 (hds per cyl) - ; So, 8MB / 0x20000 = 0x40 tracks - ld hl,0 ; starting unit track offset - ld de,$0040 ; per disk track offset - ld a,(curdisk) ; get current disk - or a ; set flags - jr z,seek2 ; disk 0 needs no offset - ld b,a ; into B for loop counter -seek1: - add hl,de ; add another offset - djnz seek1 ; and loop as needed -seek2: - push hl ; save total track offset - ld a,(curtrak) ; get current track value - push af ; save track value - and $0F ; head is low 4 bits of track - ld d,a ; save in D for head - pop af ; recover original track value - rra ; rotate to remove head bits - rra - rra - rra - and $0F ; mask off other bits - ld l,a ; save in low byte of HL - ld h,0 ; zero out high byte of HL - ld a,(cursect) ; get sector - ld e,a ; put in E - pop bc - add hl,bc ; add track offset - ld b,BF_DIOSEEK ; HBIOS seek function - ld a,(hb_dev) ; HBIOS disk unit - ld c,a ; ... goes in C - rst 08 ; do it - ret z ; if no error, done - ld a,ior_badblk ; signal I/O error - ret ; done + ; We use LBA addressing for disk access. So, we need to + ; translate the track/sector value from p-System into an + ; lba offset. Since we are using 16 sectors per track, we + ; can cheat (avoid multiplication) by using the low 4 bits + ; for sector and the high bits for track which allows us to + ; just "or" the values together. We are only using word values + ; here since that will handle up to a 32MB p-System file system + ; (slice) which is more than enough. + + ld a,(curtrak) ; cur track in accum + ld l,a ; move to low byte of HL + ld h,0 ; zero out high byte of HL + add hl,hl ; * 2 + add hl,hl ; * 4 + add hl,hl ; * 8 + add hl,hl ; * 16 (sectors per track) + ld a,(cursect) ; cur sec to accum + or l ; combine with low byte of HL + ld l,a ; back to low byte of HL + + ; HL now has LBA offset of desired sector. Next + ; we need to add in the offset of the current disk. + ; At this point, we need to start using dword values + ; using DE:HL to accommodate large disk drives. + ld de,0 ; extend LBA to DE:HL + ld bc,(curoff) ; get low word of offset + add hl,bc ; add low words together + ex de,hl ; swap high word of LBA into HL + ld bc,(curoff+2) ; get high word of offset + adc hl,bc ; add high words together (w/ carry) + ex de,hl ; swap back to get DE:HL + + ; Now we have final LBA in DE:HL. We just set the + ; LBA flag bit and do the disk seek. + set 7,d ; high order bit designates LBA I/O + ld b,BF_DIOSEEK ; HBIOS seek function + ld a,(hb_dev) ; HBIOS disk unit + ld c,a ; ... goes in C + rst 08 ; do it + ret z ; if no error, done + ld a,ior_badblk ; signal I/O error + ret ; done prtstr: - ld a,(hl) - or a - ret z - push hl - ld c,a - call conwrit - pop hl - inc hl - jr prtstr - + ; Print a null terminated string on the p-System console + ld a,(hl) ; get next char + or a ; set flags + ret z ; done if null + push hl ; save buffer pointer + ld c,a ; char to C + call conwrit ; write it out to pSys console + pop hl ; recover buffer pointer + inc hl ; increment to next char + jr prtstr ; loop as needed + +parterr: + ld hl,str_parterr ; partition error string + call prtstr ; display it + jp syshalt ; back to boot loader panic: - di - halt + ; Hard stop + di ; no interrupts + halt ; ... and halt -hb_dev .db 3 ; HBIOS disk device unit -; -curdisk .db 0 ; Current disk number -curtrak .db 0 ; Current track number -cursect .db 0 ; Current sector number -curbufr .dw 0 ; Current disk buffer address -; -str_banner .db 13,10,"RomWBW p-System BIOS v" - .db BIOSVER - .db 13,10,13,10 - .db "Press any key...",0 -; -; -; + +;----------------------------------------------------------------------- +; Local storage +;----------------------------------------------------------------------- + +hb_bnks: +hb_usr .db 0 ; HBIOS User bank id +hb_bios .db 0 ; HBIOS BIOS bank id + +hb_dev .db 0 ; HBIOS device for pSys disk +hb_con .db $FF ; HBIOS device for pSys console unit +hb_rem .db $FF ; HBIOS device for pSys remote unit +hb_prn .db $FF ; HBIOS device for pSys printer unit + +curdisk .db 0 ; Current pSys disk number +curtrak .db 0 ; Current pSys track number +cursect .db 0 ; Current pSys sector number +curbufr .dw 0 ; Current pSys disk buffer address +curoff .dw 0,0 ; Current sector offset (dword LBA) + +paroff .dw 0,0 ; Partition offset (dword LBA) +sps .dw 16384,0 ; Sectors per slice (8MB / 512) = 16384 + +str_banner .db 13,10,13,10,"RomWBW p-System Extended BIOS v" + .db BIOSVER,0 +str_parterr .db 13,10,"*** Disk partition table error!",0 + + + +#if ($ >= bios_end) + .echo "*** ERROR: Out of space in pSystem BIOS!!!\n" + !!! ; force an assembly error +#endif + +slack .equ bios_end - $ + .echo "pSystem BIOS space remaining: " + .echo slack + .echo " bytes.\n" + .fill bios_end - $ - -; + .end diff --git a/Source/pSys/biostest.dat b/Source/pSys/biostest.dat index b1b0f82a..4eb18f4b 100644 Binary files a/Source/pSys/biostest.dat and b/Source/pSys/biostest.dat differ diff --git a/Source/pSys/biostest.old b/Source/pSys/biostest.old new file mode 100644 index 00000000..17007bea Binary files /dev/null and b/Source/pSys/biostest.old differ diff --git a/Source/pSys/fill.asm b/Source/pSys/fill.asm new file mode 100644 index 00000000..7aa7184b --- /dev/null +++ b/Source/pSys/fill.asm @@ -0,0 +1,4 @@ +#include "psys.inc" + + .fill (8 * 1024) - loader_size - bios_size - boot_size - (512 * 3) + .end diff --git a/Source/pSys/fill.dat b/Source/pSys/fill.dat deleted file mode 100644 index 3f8cdec5..00000000 Binary files a/Source/pSys/fill.dat and /dev/null differ diff --git a/Source/pSys/loader.asm b/Source/pSys/loader.asm index b03cf965..d8d2f37f 100644 --- a/Source/pSys/loader.asm +++ b/Source/pSys/loader.asm @@ -170,7 +170,6 @@ skew .equ 0 ; track-to-track skew call pstr ; print it ld bc,boot_loc ; bootstrap location adr call prthexword ; print it - call nl2 ; spacing ; ; Push key values onto the stack ; @@ -198,9 +197,9 @@ skew .equ 0 ; track-to-track skew push hl ld hl,interp_base ; starting address of the interpreter push hl -#if testbios - ;ld hl,disks-1 ; maximum (highest) disk drive number - ;push hl +#ifdef TESTBIOS + ld hl,disks-1 ; maximum (highest) disk drive number + push hl #endif ; jp boot_loc ; jump to bootloader diff --git a/Source/pSys/psys.inc b/Source/pSys/psys.inc index 44039ede..63612b29 100644 --- a/Source/pSys/psys.inc +++ b/Source/pSys/psys.inc @@ -1,4 +1,3 @@ -testbios .equ 0 ; ; p-System Loader ; @@ -8,14 +7,14 @@ loader_end .equ loader_loc + loader_size ; ; p-System BIOS ; -bios_size .equ $200 +bios_size .equ $300 bios_loc .equ $FE00 - bios_size bios_end .equ bios_loc + bios_size ; ; p-System Bootstrap ; -#if testbios -boot_size .equ $300 +#ifdef TESTBIOS +boot_size .equ $400 boot_loc .equ $8000 boot_end .equ boot_loc + boot_size #else diff --git a/Source/pSys/psys.vol b/Source/pSys/psys.vol index f6baa181..63b726d8 100644 Binary files a/Source/pSys/psys.vol and b/Source/pSys/psys.vol differ diff --git a/Source/pSys/psys_ior.inc b/Source/pSys/psys_ior.inc new file mode 100644 index 00000000..d7a3dee9 --- /dev/null +++ b/Source/pSys/psys_ior.inc @@ -0,0 +1,25 @@ +; +;----------------------------------------------------------------------- +; p-System IORESULT values +;----------------------------------------------------------------------- +; +ior_ok .equ 0 ; No error +ior_badblk .equ 1 ; Bad block, CRC error (parity) +ior_baddev .equ 2 ; Bad device number +ior_badio .equ 3 ; Illegal I/O request +ior_timout .equ 4 ; Data-com timeout +ior_offlin .equ 5 ; Volume is no longer on-line +ior_nofile .equ 6 ; File is no longer in directory +ior_filnamerr .equ 7 ; Illegal file name +ior_full .equ 8 ; No room; insufficient space on disk +ior_novol .equ 9 ; No such volume on-line +ior_notfnd .equ 10 ; No such file name in directory +ior_dupfil .equ 11 ; Duplicate file +ior_notclos .equ 12 ; Not closed: attempt to open an open file +ior_notopen .equ 13 ; Not open: attempt to access a closed file +ior_badfmt .equ 14 ; Bad format: error reading real or integer +ior_bufovr .equ 15 ; Ring buffer overflow +ior_diskwp .equ 16 ; Write attempt to protected disk +ior_blknumerr .equ 17 ; Illegal block number +ior_bufadrerr .equ 18 ; Illegal buffer address +ior_badsiz .equ 19 ; Bad text file size diff --git a/Source/ver.inc b/Source/ver.inc index ca8935b0..94b122d9 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 1 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1.1-pre.192" +#DEFINE BIOSVER "3.1.1-pre.193" diff --git a/Source/ver.lib b/Source/ver.lib index 81ca464a..d1aaa179 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 1 rup equ 1 rtp equ 0 biosver macro - db "3.1.1-pre.192" + db "3.1.1-pre.193" endm