From 71a8b2b177e71360f2ed4ef69cdaf0d6c9ee46e1 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Mon, 16 Jan 2023 15:41:21 -0800 Subject: [PATCH] Finalize p-System Implementation - Implemented Extended BIOS functions - p-System slices moved into partition --- Doc/ROM Applications.pdf | Bin 194600 -> 194600 bytes Doc/RomWBW Applications.pdf | Bin 241655 -> 241655 bytes Doc/RomWBW Architecture.pdf | Bin 473136 -> 473136 bytes Doc/RomWBW Disk Catalog.pdf | Bin 134811 -> 134811 bytes Doc/RomWBW Getting Started.pdf | Bin 283712 -> 283719 bytes ReadMe.md | 6 +- ReadMe.txt | 8 +- Source/Doc/GettingStarted.md | 2 +- Source/pSys/Build.cmd | 34 +- Source/pSys/Makefile | 21 +- Source/pSys/ReadMe.txt | 124 +++--- Source/pSys/bios.asm | 784 +++++++++++++++++++++------------ Source/pSys/biostest.dat | Bin 784 -> 1024 bytes Source/pSys/biostest.old | Bin 0 -> 1024 bytes Source/pSys/fill.asm | 4 + Source/pSys/fill.dat | Bin 3584 -> 0 bytes Source/pSys/loader.asm | 7 +- Source/pSys/psys.inc | 7 +- Source/pSys/psys.vol | Bin 8380416 -> 8380416 bytes Source/pSys/psys_ior.inc | 25 ++ Source/ver.inc | 2 +- Source/ver.lib | 2 +- 22 files changed, 641 insertions(+), 385 deletions(-) create mode 100644 Source/pSys/biostest.old create mode 100644 Source/pSys/fill.asm delete mode 100644 Source/pSys/fill.dat create mode 100644 Source/pSys/psys_ior.inc diff --git a/Doc/ROM Applications.pdf b/Doc/ROM Applications.pdf index cfd947b638373b686faf55221e23cd0522a584f7..cc0b4ef09fed44d5e2f4d71752420b20fbfeab73 100644 GIT binary patch delta 134 zcmZ4SfqTUV?hSQ}OgB>|H!xPSc)wn>ulYY?`+r8p?f)5>Qckd&8d@4!nix;dI>jUd z<81Fe#bmAP>|$wPWMF9N;%MOFWMpFKZ0c&@Vq|1w;o@TH;_PT?Vy9q3NXc~WA55|U D9Wp30 delta 134 zcmZ4SfqTUV?hSQ}Op&RR8yKruJZ~@B)BK;Y{XZk)_Wz7bDJR&C4b6;AOiiX|onn%K zaklrKVzSnCb~AJ`buo2wG&8bvGcd3)v@~-xH*z*KFful9F*G-Gwo|Ynq+~kx4<=av D%^xQ| diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index 370de57cd3fd54085bb748af45728e1d28aebe30..7ada70cb091154bcef8953e02b91e7d9be988709 100644 GIT binary patch delta 162 zcmexaW z*T6#Ez(8G-OW!v?#U-&MRYAkW%E-XT*uc;bs$~0&Jm&unPEM9?ZcYX!&MvOb<`zb7 gh6aWf7S1k4&W`L0F&4)QUCw| diff --git a/Doc/RomWBW Architecture.pdf b/Doc/RomWBW Architecture.pdf index 6fb56ef56402a36a93cff691aa6e35ac50c6e316..330266819aacf80ce6c4a91d0de70f7f71275632 100644 GIT binary patch delta 220 zcmdn+L1qIG)iE*^ubAAxIF+UJ=(Zc1C7FH~3#6o^nHr>}CYzgDm?xX2SvISbZC5E{ zZ0g34Y2U`k1jNih%mT!$+qW^YCB9=fHMBIeG&Y$2z??~($H>^g&=4xJ-SGokzk7m{ znTwl&p|hKXi?OMTv5BFHlZBIsg`1<1p^1fsp_93tf(=0>u?lu}T*W1cMI{wQscBp$ QrY07KCS0njuKsRZ0AX1{2mk;8 delta 220 zcmdn+L1qIG)iE+{UOl;iaVksE_ifiUOEUc~7O*fkGf7NLHZw3wGfXu~O>0&u+pbc^ z*wl?7)4q+735c12m<5Pgw{K%)OMJ&}Y-na|Vq!S`fjN^nkCCx~p&?XcyWi%KerQq#Ch QOie5dO}JE5UH#p-06tkjv;Y7A diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf index e1e9ad78042202774fa92350f582ca51538f1f47..e41f51cbfb31f27f8f6203ecb778a5efb915984d 100644 GIT binary patch delta 137 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 delta 13136 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 @@ -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 b1b0f82ac4759086682706de3bb9d748fab1a7ec..4eb18f4bbde8838a123dae64150cc2124ed4ddf3 100644 GIT binary patch delta 274 wcmbQh*1)kLfKk|ry?NiEzD9jzY5(d?l?tCvGB9jTW?aiy&oHo{knYw408Azfc>n+a delta 32 mcmZqRn83CnfKgb)ioJQ?p}t0aW!Xa^jiNw&a&t1{T1Ei1R}0zz diff --git a/Source/pSys/biostest.old b/Source/pSys/biostest.old new file mode 100644 index 0000000000000000000000000000000000000000..17007bea128c7b85be2b09e8133d99451a6040a3 GIT binary patch literal 1024 zcmd^5&r1|h9Dl2}{=jWnOD$vHzSjiCCK=nQ!Ig-l3}PV`I*+?k4!h0D%$Ti$z4zu^ zbPGB}wG!fpfu719=r%i9TKcd3PzW-@0$v`^cVDn@9)p|rO_Yis|4jp8=*H%aM{$JsR#zQVMdC26sk117zH^DKcXT&<3OI2}C9x@`TQk|DCSc7e9 zZ{Sn~en|BYP^A+>0b$>tBc)|VU+1lzVS8_NmKk=F``Fkm#;60z( z0ijGO{#JbDQUAM({eCB0{c86IZ-GZ-=e}PJKXEt`{-ExET3+u#=~i|;(IwWm*Oor| zzuav96mcqDA4AZF)tz0HW%ebrC#2MF3 wGHy81AVZe!Oj_nJDe2X-VTTdRf)xvuNz)-&SXC}72SMo0L|J#_;QyC?0(G$_-~a#s literal 0 HcmV?d00001 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 3f8cdec5b6d6c0fc09f84593fc2ff144e6d109f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3584 lcmeIufdBvi0K=g9Qy=7oP+`D;0RsjM7%*VKfB^#!0|O2K00961 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 f6baa18198b1dd63d3b2178019a145beca42247e..63b726d88e9cbe7d8161813a6d65771860596f82 100644 GIT binary patch delta 88721 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 K4E#p}+r=NwewLg7 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