diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 33f03d82..4afcc257 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -18,6 +18,7 @@ Version 3.5 - WBW: Upgraded BBCBASIC to v5.00 - W?S: Updated FLASH utility to v1.3.9 - WBW: Support RCBus PS/2 Keyboard (EP/Sally) +- M?R: Update Timer app to display output in decimal Version 3.4 ----------- diff --git a/Doc/RomWBW Applications.pdf b/Doc/RomWBW Applications.pdf index b25e9dae..f6392b6b 100644 Binary files a/Doc/RomWBW Applications.pdf and b/Doc/RomWBW Applications.pdf differ diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf index decdd570..673cd83d 100644 Binary files a/Doc/RomWBW Disk Catalog.pdf and b/Doc/RomWBW Disk Catalog.pdf differ diff --git a/Doc/RomWBW Errata.pdf b/Doc/RomWBW Errata.pdf index 6f2ca51f..b2862f50 100644 Binary files a/Doc/RomWBW Errata.pdf and b/Doc/RomWBW Errata.pdf differ diff --git a/Doc/RomWBW ROM Applications.pdf b/Doc/RomWBW ROM Applications.pdf index e331c33e..72800f80 100644 Binary files a/Doc/RomWBW ROM Applications.pdf and b/Doc/RomWBW ROM Applications.pdf differ diff --git a/Doc/RomWBW System Guide.pdf b/Doc/RomWBW System Guide.pdf index be18328f..e01319ec 100644 Binary files a/Doc/RomWBW System Guide.pdf and b/Doc/RomWBW System Guide.pdf differ diff --git a/Doc/RomWBW User Guide.pdf b/Doc/RomWBW User Guide.pdf index 0aa6ea10..71c91d31 100644 Binary files a/Doc/RomWBW User Guide.pdf and b/Doc/RomWBW User Guide.pdf differ diff --git a/ReadMe.md b/ReadMe.md index 927ed892..7e341dba 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ **RomWBW ReadMe** \ Version 3.5 \ Wayne Warthen ([wwarthen@gmail.com](mailto:wwarthen@gmail.com)) \ -04 Jun 2024 +30 Jun 2024 # Overview diff --git a/ReadMe.txt b/ReadMe.txt index 27b1dab2..2d5ea376 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,6 +1,6 @@ RomWBW ReadMe Wayne Warthen (wwarthen@gmail.com) -04 Jun 2024 +30 Jun 2024 diff --git a/Source/Apps/timer.asm b/Source/Apps/timer.asm index b220db1a..028de3cc 100644 --- a/Source/Apps/timer.asm +++ b/Source/Apps/timer.asm @@ -1,9 +1,10 @@ ;=============================================================================== ; TIMER - Display system timer value -; +; Version 1.21 30-June-2024 ;=============================================================================== ; ; Author: Wayne Warthen (wwarthen@gmail.com) +; Updated: MartinR (June 2024) ;_______________________________________________________________________________ ; ; Usage: @@ -14,38 +15,58 @@ ; ; Operation: ; Reads and displays system timer value. +; +; This code will only execute on a Z80 CPU (or derivitive) +; +; This source code assembles with TASM V3.2 under Windows-11 using the +; following command line: +; tasm -80 -g3 -l TIMER.ASM TIMER.COM +; ie: Z80 CPU; output format 'binary' named .COM (rather than .OBJ) +; and includes a symbol table as part of the listing file. ;_______________________________________________________________________________ ; ; Change Log: ; 2018-01-14 [WBW] Initial release ; 2018-01-17 [WBW] Add HBIOS check ; 2019-11-08 [WBW] Add seconds support +; 2024-06-30 [MR ] Display values in decimal rather than hexadecimal +;_______________________________________________________________________________ +; +; Includes binary-to-decimal subroutine by Alwin Henseler +; Located at: https://www.msx.org/forum/development/msx-development/32-bit-long-ascii ;_______________________________________________________________________________ ; ; ToDo: +; Display the elapsed time in HH:MM:SS ;_______________________________________________________________________________ ; -#include "../ver.inc" +#include "../ver.inc" ; Used for building RomWBW +;#include "ver.inc" ; Used for testing purposes during code development ; ;=============================================================================== ; 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 +stksiz .equ $80 ; Working stack size (was $40) +; +restart .equ $0000 ; CP/M restart vector +bdos .equ $0005 ; BDOS invocation vector +; +ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr ; bf_sysver .equ $F1 ; BIOS: VER function bf_sysget .equ $F8 ; HBIOS: SYSGET function -bf_sysset .equ $F9 ; HBIOS: SYSGET function +bf_sysset .equ $F9 ; HBIOS: SYSSET function bf_sysgettimer .equ $D0 ; TIMER subfunction bf_syssettimer .equ $D0 ; TIMER subfunction bf_sysgetsecs .equ $D1 ; SECONDS subfunction bf_syssetsecs .equ $D1 ; SECONDS subfunction ; +; ASCII Control Characters +; +lf .equ $0A ; Line Feed +cr .equ $0D ; Carriage Return +; ;=============================================================================== ; Code Section ;=============================================================================== @@ -73,17 +94,17 @@ exit: ; clean up and return to command processor ; Initialization ; init: - call crlf ; formatting - ld de,msgban ; point to version message part 1 - call prtstr ; print it -; - call idbio ; identify active BIOS - cp 1 ; check for HBIOS - jp nz,errbio ; handle BIOS error -; + call crlf ; formatting + ld de,msgban ; point to version message part 1 + call prtstr ; print it +; + call idbio ; identify active BIOS + cp 1 ; check for HBIOS + jp nz,errbio ; handle BIOS error +; ld a,rmj << 4 | rmn ; expected HBIOS ver - cp d ; compare with result above - jp nz,errbio ; handle BIOS error + cp d ; compare with result above + jp nz,errbio ; handle BIOS error ; initx ; initialization complete @@ -120,9 +141,9 @@ process0: call crlf2 ; formatting ; process1: - ld b,bf_sysget ; HBIOS SYSGET function + ld b,bf_sysget ; HBIOS SYSGET function ld c,bf_sysgettimer ; TIMER subfunction - rst 08 ; call HBIOS, DE:HL := timer value + rst 08 ; call HBIOS, DE:HL := timer value ld a,(first) or a @@ -135,28 +156,50 @@ process1: cp l ; compare to current LSB jr z,process2 ; if equal, bypass display -process1a: +;******************************************************************************* + +; Code added/amended to print values in decimal +; MartinR June2024 + +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 - call prthex32 ; display it - ld de,strtick ; tag - call prtstr ; display it + ld a,l ; new LSB value to A + ld (last),a ; save as last value + call prtcr ; back to start of line + + call b2d32 ; Convert DE:HL into ASCII; Start of ASCII buffer returned in HL + ex de,hl + call prtstr ; Display the value + + ld de,strtick ; "Ticks" message + call prtstr ; Display it ; get and print seconds value - ld b,bf_sysget ; HBIOS SYSGET function - ld c,bf_sysgetsecs ; SECONDS subfunction - rst 08 ; call HBIOS, DE:HL := seconds value - call prthex32 ; display it - ld a,'.' ; fraction separator - call prtchr ; print it - ld a,c ; get fractional component - call prthex ; print it - ld de,strsec ; tag - call prtstr ; display it -; + ld b,bf_sysget ; HBIOS SYSGET function + ld c,bf_sysgetsecs ; SECONDS subfunction + rst 08 ; Call HBIOS; DE:HL := seconds value; C := fractional part + push bc ; Preserve the fractional part on the stack + + call b2d32 ; Convert DE:HL into ASCII; Start of ASCII buffer returned in HL + ex de,hl + call prtstr ; Display the value + + ld a,'.' ; Fraction separator, ie decimal point + call prtchr ; Print it + + pop bc ; Retrieve fractional part into A + ld a,c + sla a ; Double the 50Hz 'ticks' value to give 1/100s of a second + + call b2d8 ; Convert into ASCII - up to 3 digits + ex de,hl ; Start of ASCII buffer returned in HL + call prtstr ; Display fractional part of the value + + ld de,strsec ; "Seconds" message + call prtstr ; Display it + +;******************************************************************************* + process2: ld a,(cont) ; continuous display? or a ; test for true/false @@ -269,9 +312,9 @@ prtdot: ; prtcr: ; - ; shortcut to print a dot preserving all regs + ; shortcut to print carriage return preserving all regs push af ; save af - ld a,13 ; load CR value + ld a,cr ; load CR value call prtchr ; print it pop af ; restore af ret ; done @@ -477,6 +520,124 @@ err2: ; without the string or $FF ; signal error ret ; done ; +; +;=============================================================================== +; Subroutine to print decimal numbers +;=============================================================================== +; +; Combined routine for conversion of different sized binary numbers into +; directly printable ASCII(Z)-string +; Input value in registers, number size and -related to that- registers to fill +; is selected by calling the correct entry: +; +; entry input decimal value 0 to: +; b2d8 A 255 (3 digits) +; b2d16 HL 65535 5 " +; b2d24 E:HL 16777215 8 " +; b2d32 DE:HL 4294967295 10 " +; b2d48 BC:DE:HL 281474976710655 15 " +; b2d64 IX:BC:DE:HL 18446744073709551615 20 " +; +; The resulting string is placed into a small buffer attached to this routine, +; this buffer needs no initialization and can be modified as desired. +; The number is aligned to the right, and leading 0's are replaced with spaces. +; On exit HL points to the first digit, (B)C = number of decimals +; This way any re-alignment / postprocessing is made easy. +; Changes: AF,BC,DE,HL,IX +; +; by Alwin Henseler +; https://msx.org/forum/topic/who-who/dutch-hardware-guy-pops-back-sort +; +; Found at: +; https://www.msx.org/forum/development/msx-development/32-bit-long-ascii +; +; Tweaked to assemble using TASM 3.2 by MartinR 23June2024 +; +b2d8: ld h,0 + ld l,a +b2d16: ld e,0 +b2d24: ld d,0 +b2d32: ld bc,0 +b2d48: ld ix,0 ; zero all non-used bits +b2d64: ld (b2dinv),hl + ld (b2dinv+2),de + ld (b2dinv+4),bc + ld (b2dinv+6),ix ; place full 64-bit input value in buffer + ld hl,b2dbuf + ld de,b2dbuf+1 + ld (hl),' ' +b2dfilc:.equ $-1 ; address of fill-character + ld bc,18 + ldir ; fill 1st 19 bytes of buffer with spaces + ld (b2dend-1),bc ; set BCD value to "0" & place terminating 0 + ld e,1 ; no. of bytes in BCD value + ld hl,b2dinv+8 ; (address MSB input)+1 + ld bc,$0909 + xor a +b2dskp0:dec b + jr z,b2dsiz ; all 0: continue with postprocessing + dec hl + or (hl) ; find first byte <> 0 + jr z,b2dskp0 +b2dfnd1:dec c + rla + jr nc,b2dfnd1 ; determine no. of most significant 1-bit + rra + ld d,a ; byte from binary input value +b2dlus2:push hl + push bc +b2dlus1:ld hl,b2dend-1 ; address LSB of bcd value + ld b,e ; current length of BCD value in bytes + rl d ; highest bit from input value -> carry +b2dlus0:ld a,(hl) + adc a,a + daa + ld (hl),a ; double 1 BCD byte from intermediate result + dec hl + djnz b2dlus0 ; and go on to double entire BCD value (+carry!) + jr nc,b2dnxt + inc e ; carry at MSB -> BCD value grew 1 byte larger + ld (hl),1 ; initialize new MSB of BCD value +b2dnxt: dec c + jr nz,b2dlus1 ; repeat for remaining bits from 1 input byte + pop bc ; no. of remaining bytes in input value + ld c,8 ; reset bit-counter + pop hl ; pointer to byte from input value + dec hl + ld d,(hl) ; get next group of 8 bits + djnz b2dlus2 ; and repeat until last byte from input value +b2dsiz: ld hl,b2dend ; address of terminating 0 + ld c,e ; size of bcd value in bytes + or a + sbc hl,bc ; calculate address of MSB BCD + ld d,h + ld e,l + sbc hl,bc + ex de,hl ; HL=address BCD value, de=start of decimal value + ld b,c ; no. of bytes BCD + sla c ; no. of bytes decimal (possibly 1 too high) + ld a,'0' + rld ; shift bits 4-7 of (HL) into bit 0-3 of A + cp '0' ; (HL) was > 9h? + jr nz,b2dexph ; if yes, start with recording high digit + dec c ; correct number of decimals + inc de ; correct start address + jr b2dexpl ; continue with converting low digit +b2dexp: rld ; shift high digit (HL) into low digit of a +b2dexph:ld (de),a ; record resulting ascii-code + inc de +b2dexpl:rld + ld (de),a + inc de + inc hl ; next BCD-byte + djnz b2dexp ; and go on to convert each BCD-byte into 2 ASCII + sbc hl,bc ; return with HL pointing to 1st decimal + ret + +b2dinv .fill 8 ; space for 64-bit input value (LSB first) +b2dbuf .fill 20 ; space for 20 decimal digits +b2dend .db 0 ; space for terminating character +; ;=============================================================================== ; Storage Section ;=============================================================================== @@ -487,20 +648,21 @@ 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 +stack .equ $ ; new stack top ; ; Messages ; -msgban .db "TIMER v1.1, 10-Nov-2019",13,10 - .db "Copyright (C) 2019, 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 +msgban .db "TIMER v1.21, 30-Jun-2024",cr,lf + .db "Copyright (C) 2019, Wayne Warthen, GNU GPL v3",cr,lf + .db "Updated by MartinR 2024",0 +msguse .db "Usage: TIMER [/C] [/?]",cr,lf + .db " ex. TIMER (display current timer value)",cr,lf + .db " TIMER /? (display version and usage)",cr,lf .db " TIMER /C (display timer value continuously)",0 msgprm .db "Parameter error (TIMER /? for usage)",0 msgbio .db "Incompatible BIOS or version, " .db "HBIOS v", '0' + rmj, ".", '0' + rmn, " required",0 -strtick .db " Ticks, ",0 -strsec .db " Seconds",0 +strtick .db " Ticks ",0 +strsec .db " Seconds ",0 ; - .end + .end diff --git a/Source/Doc/SystemGuide.md b/Source/Doc/SystemGuide.md index c9cdb2ea..e07d63af 100644 --- a/Source/Doc/SystemGuide.md +++ b/Source/Doc/SystemGuide.md @@ -126,6 +126,142 @@ execution. ![Bank Switched Memory Layout](Graphics/BankSwitchedMemory){ width=100% } +## Bank Id + +RomWBW utilizes a specific assignment of memory banks for dedicated +purposes. A numeric Bank Id is used to refer to the memory banks. The +Bank Id is a single byte. In general, the Bank Id simply refers to each +of the 32K banks in sequential order. In other words, Bank Id 0 is the +first physical 32K, Bank Id 1 is the second, etc. However, the high +order bit of the Bank Id has a special meaning. If it is 0, it indicates +a ROM bank is being referred to. If it is 1, it indicates a RAM bank +is being referred to. + +For example, let's say we have a typical system with 512KB of ROM and +512KB of RAM. The Bank Ids would look like this: + +| Physical Memory | Type | Physical Bank | Bank Id | +|-------------------|------|---------------|-----------| +| 0x000000-0x007FFF | ROM | 0 | 0x00 | +| 0x008000-0x00FFFF | ROM | 1 | 0x01 | +| 0x010000-0x07FFFF | ROM | 2-15 | 0x02-0x0F | +| 0x080000-0x087FFF | RAM | 16 | 0x80 | +| 0x088000-0x08FFFF | RAM | 17 | 0x81 | +| 0x090000-0x0FFFFF | RAM | 18-31 | 0x82-0x8F | + +Note that Bank Id 0x00 is **always** the first bank of ROM and 0x80 is +**always** the first bank of RAM. If there were more banks of physical ROM, +they would be assigned Bank Ids starting with 0x10. Likewise, additional +bank of physical RAM would be assigned Bank Ids starting with 0x90. + +The Bank Id is used in all RomWBW API functions when referring to +the mapping of banks to the lower 32K bank area of the processor. In +this way, all RomWBW functions can refer to a generic Bank Id without +needing to understand how a specific hardware platform accesses the +physical memory areas. A single routine within the HBIOS is implemented +for each memory manager that maps Bank Ids to physical memory. + +## Bank Assignments + +RomWBW requires dedicated banks of memory for specific purposes. It +uses Bank Ids via an algorithm to make these assignments. The following +table describes the way the banks are assigned. The Typical column +shows the specific values that would be assigned for a common system +with 512KB of ROM and 512KB of RAM (nROM=16, nRAM=16). + +| Bank Id | Identity | Typical | Purpose | +|-------------------|-----------|---------|------------------------------------------| +| 0x00 |BID_BOOT | 0x00 | Boot Bank (HBIOS image) | +| 0x01 |BID_IMG0 | 0x01 | Boot Loader, Monitor, ROM OSes, ROM Apps | +| 0x02 |BID_IMG1 | 0x02 | ROM Apps | +| 0x03 |BID_IMG2 | 0x03 | \ | +| 0x04 |BID_ROMD0 | 0x04 | First ROM Disk Bank | +| nROM - 1 | | 0x0F | Last ROM Disk Bank | +| 0x80 |BID_BIOS | 0x80 | HBIOS (working copy) | +| 0x81 |BID_RAMD0 | 0x81 | First RAM Disk Bank | +| 0x80 + nRAM - 8 | | 0x88 | Last RAM Disk Bank | +| 0x80 + nRAM - 7 |BID_APP0 | 0x89 | First Application Bank | +| 0x80 + nRAM - 5 | | 0x8B | Last Application Bank | +| 0x80 + nRAM - 4 |BID_BUF | 0x8C | OS Disk Buffers | +| 0x80 + nRAM - 3 |BID_AUX | 0x8D | OS Code Bank | +| 0x80 + nRAM - 2 |BID_USR | 0x8E | User Bank (CP/M TPA) | +| 0x80 + nRAM - 1 |BID_COM | 0x8F | Common Bank | + +In this table, nROM and nRAM refer to the number of corresponding +ROM and RAM banks in the the system. + +The contents of the banks referred to above are described in more detail +below: + +Boot Bank: + +: The Boot Bank receives control when a system is first powered +on. It contains a ROM (read-only) copy of the HBIOS. At boot, it does +minimal hardware initialization, then copies itself to the HBIOS bank +in RAM, then resumes execution from the RAM bank. + +Boot Loader: + +: The application that handles loading of ROM or Disk based applications +including operating systems. It copies itself to a RAM bank at the +start of it's execution. + +Monitor: + +: The application that implements the basic system monitor functions. +It copies itself to a RAM bank at the start of it's execution. + +ROM OSes: + +: Code images of CP/M 2.2 and Z-System which are copied to RAM and +executed when a ROM-based operating system is selected in the Boot +Loader. + +ROM Applications: + +: Various ROM-based application images such as BASIC, FORTH, etc. They +can be selected in the Boot Loader. The Boot Loader will copy the +application image to a RAM bank, then transfer control to it. + +ROM Disk: + +: A sequential series of banks assigned to provide the system ROM Disk +contents. + +HBIOS: + +: This bank hosts the running copy of the RomWBW HBIOS. + +RAM Disk: + +: A sequential series of banks assigned to provide the system RAM Disk. + +Application Bank: + +: A sequential series of banks that are available for use by applications +that wish to utilize banked memory. + +OS Disk Buffers: + +: This bank is used by CP/M 3 and ZPM3 for disk buffer storage. + +OS Code Bank: + +: This bank is used by CP/M 3 and ZPM3 as an alternate bank for code. +This allows these operating systems to make additional TPA space +available for applications. + +User Bank: + +: This is the default bank for applications to use. This includes the +traditional TPA space for CP/M. + +Common Bank: + +: This bank is mapped to the upper 32K of the processors memory space. +It is a fixed mapping that is never changed in normal RomWBW operation +hence the name "Common". + # System Boot Process A multi-phase boot strategy is employed. This is necessary because at diff --git a/Source/ver.inc b/Source/ver.inc index 9a3e8415..aad10afa 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 5 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.5.0-dev.47" +#DEFINE BIOSVER "3.5.0-dev.48" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index 7348e693..3d855c09 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 5 rup equ 0 rtp equ 0 biosver macro - db "3.5.0-dev.47" + db "3.5.0-dev.48" endm