Files
RomWBW/Source/Apps/Mode.asm
b1ackmai1er 78f65522b7 Dev (#108)
* added hack to handle tunes

* quiet clean

* added chmod for execution

* suppress warnings

* Multi-boot fixes

* the windows build somehow thinks that these filesystems are cpm3.

* credit and primitive instructions

* Update sd.asm

Cosmetic fix.

* make compile shut up about conditionals

* Add bin2asm for linus and update build to process font files under linix

* fixed quoted double quote bug, added tests

* added tests

* added bin2asm for font file source creation

* Revert linux bin2asm font stuff

* added rule for font source generation

* build fonts

* added directory mapping cache.  if the same directory is being hit
as last run, we don't need to rebuild the map.  will likely break if
you are running more than one at a time, in that the cache will be
ineffective.  also, if the directory contents change, this will also break.

* removed strip.  breaks osx

* added directory tag so . isn't matched all over the place

* added real cache validation

* fixed build

* this file is copied from optdsk.lib or optcmd.lib

* install to ../HBIOS

* prerequisite verbosity

* diff soft failure and casefn speedup

* added lzsa

* added lzsa

* removed strip. breaks on osx

* added clobber

* added code to handle multiple platform rom builds with rom size override

* added align and 0x55 hex syntax

* default to hd64180

* added N8 capability

* added SBC_std.rom to default build

* added support for binary diff

* diff fixes

* clean, identical build.  font source generator emitted .align.  this does not match the windows build

* Upgrade NZCOM to latest

* Misc. Cleanup

* fixed expression parser bug : ~(1|2) returned 0xfe

* added diff build option

* Update Makefile

Makefile enhancement to better handle ncurses library from Bob Dunlop.

* Update sd.asm

Back out hack for uz80as now that Curt fixed it.

* Misc. Cleanup

* UNA Catchup

UNA support was lacking some of the more recent behavior changes.  This corrects most of it.

* Add github action for building RomWBW

* Bump Pre-release Version

* Update build.yml

Added "make clean" which will remove temporary files without removing final binary outputs.

* Update Makefile

Build all ROM variants by default in Linux/Mac build.

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update for GitHub Build

Case issue in TASM includes showing up in GitHub build.  This should correct that.

* Added an gitignore files to exclude generated files

* Removed Tunes/clean.cmd and Tunes/ReadMe.txt - as make clean removes them

* Build.sh: marked as executable

chmod +x Build.sh

* Fix to HBIOS/build.sh

When adding files to rom disk, if files were missing, it would error out.

It appears the intent is to skip non-existing files.

Updated to log out correctly for missing files - and continue operation.

* Update Microsoft NASCOM BASIC.docx

Nascom manual, text version by Jan S (full name unknown)

* Fix issue with Apps/Tune not making

If dest directory does not exist, fails to make Apps

* Create ReadMe.txt

* Update Makefile

* Update Build.sh

* Make .gitignores for Tools/unix more specific

* cpmtools Update

Updated cpmtools applications (Windows only).  Removed hack in diskdefs that is no longer required.

* HBIOS Proxy Temp Stack Enhancement

Reuse the bounce buffer area as the temporary stack space required briefly in HBX_INVOKE when transitioning banks.  Increases size of temporary stack space to 64 bytes.

* Update ReadMe.txt

* HBIOS - clean up TMPSTK

* Update hbios.asm

Minor cosmetic changes.

* Build Process Updates

Minor udpates to build process to improve consistency between Windows and Mac/Linux builds.

* Update hbios.asm

Add improved interrupt protection to HBIOS PEEK, POKE, and BNKCPY functions.

* hbios - wrap hbx_bnkcpy

* hbios - adjust hbx_peek hbx_poke guards

* Update hbios.asm

Adjusted used of DI/EI for PEEK and POKE to regain a bit of INTSTK space.  Added code so that HB_INVBNK can be used as a flag indicating if HBIOS is active, $FF is inactive, anything else means active.

* Add HBIOS MuTex

* Initial Nascom basic ecb-vdu graphics

set and reset for 80x25b screen with 256 character mod

* Finalize Pre-release 34

Final support for FreeRTOS

* Update nascom.asm

Optimization, cleanup, tabs and white spaces

* IDE & PPIDE Cleanup

* Clean up

Make version include files common.

* Update Makefile

* Update Makefile

* Build Test

* Build Test

* Build Fixes

* Update nascom.asm

Cleanup

* Update nascom.asm

Optimization

* hbios - temp stack tweak

* Update hbios.asm

Comments on HBX_BUF usage.

* Update nascom.asm

Optimization

* Update nascom.asm

Setup ECB-VDU build option, remove debug code

* Update nascom.asm

Set default build. update initialization

* Update nascom.asm

Make CLS clear vdu screen

* Update nascom.asm

Fixup top screen line not showing

* Add SC131 Support

Also cleaned up some ReadMe files.

* HBIOS SCZ180 - remove mutex special files

* HBIOS SCZ180 - adjust mutex comment

* Misc. Cleanup

Includes some minor improvements to contents in some disk images.

* Delete FAT.COM

Changing case of FAT.COM extension to lowercase.

* Create FAT.com

Completing change of case in extension of FAT.com.

* Update Makefile

Remove ROM variants that just have the HBIOS MUTEX enabled.  Users can easily enable this in a custom build.

* Cleanup

Removed hack from Images Makefile.  Fixed use of DEFSERCFG in various places.

* GitHub CI Updates

Adds automation of build and release assets upon release.

* Prerelease 36

General cleanup

* Build Script Cleanups

* Config File Cleanups

* Update RomWBW Architecture

General refresh for v2.9.2

* Update vdu.asm

Removed a hack in VDU driver that has existed for 8 years.  :-)

* Fix CONSOLE Constant

Rename CIODEV_CONSOLE constant to CIO_CONSOLE because it is a unit code, not a device type code.

Retabify TastyBasic.

* Minor Bug Fixes

- Disk assignment edge case
- CP/M 3 accidental fall thru
- Cosmetic updates

* Update util.z80

* Documentation Cleanup

* Documentation Update

* Documentation Update

* Documentation Updates

* Documentation Updates

* Create Common.inc

* Documentation Updates

* Documentation Updates

* doc - a few random fixes

* Documentation Cleanup

* Fix IM 0 Build Error in ACIA

* Documentation Updates

* Documentation Cleanup

* Remove OSLDR

The OSLDR application was badly broken and almost impossible to fix with new expanded OS support.

* Bug Fixes

- Init RAM disk at boot under CP/M 3
- Fix ACR activation in TUNE

* FD Motor Timeout

- Made FDC motor timeout smaller and more consistent across different speed CPUs
- Added "boot" messaging to RTC

* Cleanup

* Cleanup

- Fix SuperZAP to work under NZCOM and ZPM3
- Finalize standard config files

* Minor Changes

- Slight change to ZAP configuration
- Added ZSDOS.ZRL to NZCOM image

* ZDE Upgrade

- Upgraded ZDE 1.6 -> 1.6a

* Config File Tuning

* Pre-release for Testing

* cfg - mutex consistent config language

* Bump to Version 3.0

* Update SD Card How-To

Thanks David!

* update ReadMe.md

Remove some odd `\`.

* Update ReadMe.txt

* Update ReadMe.md

* Update Generated Doc Files

* Improve XModem Startup

- Extended startup timeout for XM.COM so that it doesn't timeout so quickly while host is selecing a file to send.
- Updated SD Card How-To from David Reese.

* XModem Timing Refinements

* TMS Driver Z180 Improvements

- TMS driver udpated to insert Z180 I/O waitstates internally so other code can run at full speed.
- Updated How-To documents from David.
- Fixed TUNE app to properly restore Z180 I/O waitstates after manipulating them.

* CLRDIR and ZDE updates

- CLRDIR has been updated by Max Scane for CP/M 3 compatibility.
- A minor issue in the preconfigured ZDE VT100 terminal escape sequences was corrected.

* Fix Auto CRT Console Switch on CP/M 3

* Handle lack of RTC better

DSRTC driver now correctly returns an error if there is no RTC present.

* Minor RTC Updates

* Finalize v3.0.1

Cleanup release for v3.0

* New ROMLDR and INTRTC driver

- Refactored romldr.asm
- Added new periodic timer based RTC driver

* CP/M 3 Date Hack

- Hack to allow INTRTC to increment time without destroying the date

* Update romldr.asm

Work around minor Linux build inconsistency

* Update Apps for New Version

* Revert "Update Apps for New Version"

This reverts commit ad80432252.

* Revert "Update romldr.asm"

This reverts commit 4a9825cd57.

* Revert "CP/M 3 Date Hack"

This reverts commit 153b494e61.

* Revert "New ROMLDR and INTRTC driver"

This reverts commit d9bed4563e.

* Start v3.1 Development

* Update FDISK80.COM

Updated FDISK80 to allow reserving up to 256 slices.

* Update sd.asm

For Z180 CSIO, ensure that xmit is finished, before asserting CS for next transaction.

* Add RC2014 UART, Improve SD protocol fix

- RC2014 and related platforms will autodetect a UART at 0xA0 and 0xA8
- Ensure that CS fully brackets all SD I/O

* ROMLDR Improvements

.com files can now be started from CP/M and size of .com files has been reduced so they always fit.

* Update commit.yml

Run commit build in all branches

* Update commit.yml

Run commit build for master and dev branches

* Improved clock driver auto-detect/fallback

* SIO driver now CTC aware

The SIO driver can now use a CTC (if available) to provide much more flexible baud rate programming.

* CTC driver fine tuning

* Update xmdm125.asm

Fixed a small issue in core XM125 code that caused a file write error message to not be displayed when it should be.

* CF Card compatibility improvement

Older CF Cards did not reset IDE registers to defaults values when reset.  Implemented a work around.

* Update ACIA detection

ACIA should no longer be detected if there is also a UART module in the system.

* Handle CTC anomaly

Small update to accommodate CTC behavior that occurs when the CTC trigger is more than half the CTC clock.

* Update acia.asm

Updated ACIA detection to use primary ACIA port instead of phantom port.

* Update acia.asm

Fix bug in ACIA detection.

Thanks Alan!

* MacOS Build Improvement

Build script updated to improve compatibility with MacOS.

Credit to Fredrik Axtelius for this.

* HBIOS Makefile - use env vars for target

Allow build ROM targets to be restricted to just one platform thru use of ENV vars:

ROM_PLATFORM - if defined to a known platform, only this platform is build - defaults to std config
ROM_CONFIG - sets the desired platform config - defaults to std

if the above ENVs are not defined, builds all ROMs

* Added some more gitignores

* Whitespace changes (crlf)

* HBIOS: Force the assembly to fail for vdu drivers if function table count is not correct

* Whitespace: trailing whitespaces

* makefile: updated some make scripts to use  when calling subdir makefiles

* linux build: update to Build.sh fix for some platforms

The initialization of the Rom dat file used the pipe (|) operator to build an initial empty file.

But the pipe operator | may sometimes return a non-zero exit code for some linux platforms, if the
the streams are closed before dd has fully processed the stream.

This issue occured on a travis linux ubuntu image.

Solution was to change to redirection.

* Bump version

* Enhance CTC periodic timer

Add ability to use TIMER mode in CTC driver to generate priodic interrupts.

* HBIOS: Added support for sound drivers

New sound driver support with initial support for the SN76489 chip

New build configuration entry:
* SN76489ENABLE

Ports are currently locked in with:
* SN76489_PORT_LEFT       .EQU    $FC     ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT)
* SN76489_PORT_RIGHT      .EQU    $F8     ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT)

* Miscellaneous Cleanup

No functional changes.

Co-authored-by: curt mayer <curt@zen-room.org>
Co-authored-by: Wayne Warthen <wwarthen@gmail.com>
Co-authored-by: ed <linux@maidavale.org>
Co-authored-by: Dean Netherton <dnetherton@dius.com.au>
Co-authored-by: ed <ed@maidavale.org>
Co-authored-by: Phillip Stevens <phillip.stevens@gmail.com>
Co-authored-by: Dean Netherton <dean.netherton@gmail.com>
2020-04-24 06:17:22 +08:00

1041 lines
25 KiB
NASM

;===============================================================================
; MODE - Display and/or modify device configuration
;
;===============================================================================
;
; Author: Wayne Warthen (wwarthen@gmail.com)
;_______________________________________________________________________________
;
; Usage:
; MODE /?
; MODE COM<n>: [<baud>[,<parity>[,<databits>[,<stopbits>]]]] [/P]
;
; <baud> is numerical baudrate
; <parity> is (N)one, (O)dd, (E)ven, (M)ark, or (S)pace
; <databits> is number of data bits, typically 7 or 8
; <stopbits> is number of stop bits, typically 1 or 2
; /P prompts user prior to setting new configuration
;
; Examples:
; MODE /? (display command usage)
; MODE (display configuration of all serial ports)
; MODE COM0: (display configuration of serial unit 0)
; MODE COM1: 9600,N,8,1 (set serial unit 1 configuration)
;
; Notes:
; - Parameters not provided will remain unchanged
; - Device must support specified configuration
;_______________________________________________________________________________
;
; Change Log:
; 2017-08-16 [WBW] Initial release
; 2017-08-28 [WBW] Handle UNACPM
; 2018-07-24 [WBW] Fixed bug in getnum23 routine (credit Phil Summers)
;_______________________________________________________________________________
;
; ToDo:
; 1) Implement flow control settings
;_______________________________________________________________________________
;
;===============================================================================
; Definitions
;===============================================================================
;
stksiz .equ $40 ; Working stack size
;
restart .equ $0000 ; CP/M restart vector
bdos .equ $0005 ; BDOS invocation vector
;
ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr
;
rmj .equ 3 ; intended CBIOS version - major
rmn .equ 1 ; intended CBIOS version - minor
;
bf_cioinit .equ $04 ; HBIOS: CIOINIT function
bf_cioquery .equ $05 ; HBIOS: CIOQUERY function
bf_ciodevice .equ $06 ; HBIOS: CIODEVICE function
bf_sysget .equ $F8 ; HBIOS: SYSGET function
;
;===============================================================================
; Code Section
;===============================================================================
;
.org $100
;
; setup stack (save old value)
ld (stksav),sp ; save stack
ld sp,stack ; set new stack
;
; initialization
call init ; initialize
jr nz,exit ; abort if init fails
;
; get the target device
call getdev ; parse device/id from command line
jr nz,exit ; abort on error
;
; process the configuration request
call process ; parse device/id from command line
jr nz,exit ; abort on error
;
exit: ; clean up and return to command processor
call crlf ; formatting
ld sp,(stksav) ; restore stack
jp restart ; return to CP/M via restart
ret ; return to CP/M w/o restart
;
; Initialization
;
init:
; locate start of cbios (function jump table)
ld hl,(restart+1) ; load address of CP/M restart vector
ld de,-3 ; adjustment for start of table
add hl,de ; HL now has start of table
ld (bioloc),hl ; save it
;
; check for UNA (UBIOS)
ld a,($FFFD) ; fixed location of UNA API vector
cp $C3 ; jp instruction?
jr nz,initwbw ; if not, not UNA
ld hl,($FFFE) ; get jp address
ld a,(hl) ; get byte at target address
cp $FD ; first byte of UNA push ix instruction
jr nz,initwbw ; if not, not UNA
inc hl ; point to next byte
ld a,(hl) ; get next byte
cp $E5 ; second byte of UNA push ix instruction
jr nz,initwbw ; if not, not UNA
;
; UNA initialization
ld hl,unamod ; point to UNA mode flag
ld (hl),$FF ; set UNA mode flag
ld a,$FF ; assume max units for UNA
ld (comcnt),a ; ... and save it
jr initx ; UNA init done
;
initwbw:
; get location of config data and verify integrity
ld hl,(ident) ; HL := adr or RomWBW HBIOS ident
ld a,(hl) ; get first byte of RomWBW marker
cp 'W' ; match?
jp nz,errinv ; abort with invalid config block
inc hl ; next byte (marker byte 2)
ld a,(hl) ; load it
cp ~'W' ; match?
jp nz,errinv ; abort with invalid config block
inc hl ; next byte (major/minor version)
ld a,(hl) ; load it
cp rmj << 4 | rmn ; match?
jp nz,errver ; abort with invalid os version
;
; RomWBW initialization
ld b,bf_sysget ; BIOS SYSGET function
ld c,$00 ; CIOCNT subfunction
rst 08 ; E := serial device unit count
ld a,e ; count to A
ld (comcnt),a ; save it
;
initx
; initialization complete
xor a ; signal success
ret ; return
;
; Get target device specification (e.g., "COM1:") and save
; as devicetype/id.
;
getdev:
; skip to start of first parm
ld ix,$81 ; point to start of parm area (past len byte)
call nonblank ; skip to next non-blank char
jp z,prtcomall ; no parms, show all active ports
;
getdev1:
; process options (if any)
cp '/' ; option prefix?
jr nz,getdev2 ; not an option, continue
call option ; process option
ret nz ; some options mean we are done (e.g., "/?")
inc ix ; skip option character
call nonblank ; skip whitespace
jr getdev1 ; continue option checking
;
getdev2:
; parse device mnemonic (e.g., "COM1") into tmpstr
call getalpha ; extract alpha portion (e.g., "COM")
call getnum ; extract numeric portion
jp c,errunt ; handle overflow as invalid unit
ld (unit),a ; save as unit number
;
; skip terminating ':' in device spec
ld a,(ix) ; get current char
cp ':' ; colon?
jr nz,getdev3 ; done if no colon
inc ix ; otherwise, skip the colon
;
getdev3:
call nonblank ; gobble any remaining whitespace
xor a ; indicate success
ret ; and return
;
; Process device
;
process:
; match and branch according to device mnemonic
ld hl,tmpstr ; point to start of extracted string
ld de,strcom ; point to "COM" string
call strcmp ; and compare
jp z,comset ; handle COM port configuration
jp errdev ; abort if bad device name
;
; Display or change serial port configuration
;
comset:
; check for valid unit number
ld hl,comcnt ; point to com device unit count
ld a,(unit) ; get com device unit count
cp (hl) ; compare to count (still in E)
jr c,comset1 ; unit < count, continue
jp errunt ; handle unit number error
;
comset1:
call ldcom ; load config for port
;
ld a,(comatr) ; get attributes
bit 7,a ; terminal?
jp nz,prtcom ; terminal not configurable
;
ld a,(ix) ; get current char
cp 0 ; nothing more?
jp z,prtcom ; no config parms, print current device config
;
; parse and update baudrate
ld a,(ix) ; get current byte
cp '0' ; check for
jr c,comset1a ; ... valid digit
cp '9'+1 ; ... else jump ahead
jr nc,comset1a ; ... to handle empty
;
call getnum32 ; get baud rate into DE:HL
jp c,errcfg ; Handle overflow error
ld c,75 ; Constant for baud rate encode
call encode ; encode into C:4-0
jp nz,errcfg ; Error if encode fails
ld a,(comcfg+1) ; Get high byte of config
and %11100000 ; strip out old baud rate bits
or c ; insert new baud rate bits
ld (comcfg+1),a ; save it
;
comset1a:
; parse and update parity
call nonblank ; skip blanks
jp z,comset9 ; end of parms
cp ',' ; comma, as expected?
jp nz,comset8 ; check for trailing options
inc ix ; skip comma
call nonblank ; skip possible blanks
call ucase
; lookup parity value
ld c,0
cp 'N'
jr z,comset2
ld c,1
cp 'O'
jr z,comset2
ld c,3
cp 'E'
jr z,comset2
ld c,5
cp 'M'
jr z,comset2
ld c,7
cp 'S'
jr z,comset2
jr comset3 ; unexpected parity char, possibly empty
;
comset2:
; update parity value
ld a,c ; new parity value to A
rlca ; rotate to bits 5-3
rlca ;
rlca ;
ld c,a ; and back to C
ld a,(comcfg) ; parity is in comcfg:5-3
and %11000111 ; strip old value
or c ; apply new value
ld (comcfg),a ; and save it
inc ix ; bump past parity char
;
comset3:
; parse & update data bits
call nonblank ; skip blanks
jr z,comset9 ; end of parms
cp ',' ; comma, as expected?
jr nz,comset8 ; check for trailing options
inc ix ; skip comma
call nonblank ; skip possible blanks
sub '5' ; normalize value
cp 4 ; value should now be 0-3
jr nc,comset4 ; unexpected, possibly empty
ld c,a ; move new value to C
ld a,(comcfg) ; data bits is in comcfg:1-0
and %11111100 ; strip old value
or c ; apply new value
ld (comcfg),a ; and save it
inc ix ; bump past data bits char
;
comset4:
; parse & update stop bits
call nonblank ; skip blanks
jr z,comset9 ; end of parms
cp ',' ; comma, as expected?
jr nz,comset8 ; check for trailing options
inc ix ; skip comma
call nonblank ; skip possible blanks
sub '1' ; normalize value
cp 2 ; value should now be 0-1
jr nc,comset8 ; unexpected, possibly empty
rlca ; rotate to bit 2
rlca
ld c,a ; move new value to C
ld a,(comcfg) ; stop bit is in comcfg:2
and %11111011 ; strip old value
or c ; apply new value
ld (comcfg),a ; and save it
inc ix ; bump past stop bits char
;
comset8:
; trailing options
call nonblank ; skip blanks
jr z,comset9 ; end of parms
cp '/' ; option introducer?
jp nz,errprm ; parameter error
inc ix ; bump part '/'
ld a,(ix) ; get character
call ucase ; make upper case
cp 'P' ; only valid option
jp nz,errprm ; parameter error
ld a,$FF ; set prompt value on
ld (pflag),a ; save it
inc ix ; bump past character
jr comset8 ; process more parms
;
comset9:
; display new config
ld de,(comcfg) ; get new config
call prtcom ; print it
ld a,(pflag) ; get prompt flag
or a ; set flags
jr z,comset9b ; bypass if not requested
call crlf2 ; spacing
ld de,indent ; indent
call prtstr ; do it
ld de,msgpmt ; point to prmopt message
call prtstr ; print it
;
ld b,64
comset9a:
xor a
call prtchr
djnz comset9a
;
comset9b:
; check for UNA
ld a,(unamod) ; get UNA flag
or a ; set flags
jr nz,comsetu ; go to UNA variant
;
; implement new config
ld de,(comcfg) ; get new config value to DE
ld b,bf_cioinit ; BIOS serial init
ld a,(unit) ; get serial device unit
ld c,a ; ... into C
rst 08 ; call HBIOS
jp nz,errcfg ; handle error
jr comsetx ; common exit
;
comsetu:
; implement new config under UNA
ld de,(comcfg) ; get new config value to DE
ld c,$10 ; UNA INIT function
ld a,(unit) ; get serial device unit
ld b,a ; ... into B
rst 08 ; call HBIOS
jp nz,errcfg ; handle error
jr comsetx ; common exit
;
comsetx:
ld a,(pflag) ; get prompt flag
or a ; set flags
jr z,comsetx2 ; bypass if not requested
comsetx1:
ld c,$01 ; console read
call bdos ; do it
cp $0D ; CR?
jr nz,comsetx1 ; loop as needed
;
comsetx2:
xor a
ret
;
; Print configuration of all serial ports
;
prtcomall:
ld a,(comcnt) ; get com device unit count
ld b,a ; init B as loop counter
ld c,0 ; init C as unit index
;
prtcomall1:
push bc ; save loop control
;
; get port info
ld a,c ; put unit number
ld (unit),a ; ... into unit
call ldcom ; get config
jr z,prtcomall2 ; no error, continue
pop bc ; unwind stack
ret ; and return with NZ
;
prtcomall2:
; print config for port
call prtcom ; print line for this port
;
; loop as needed
pop bc ; restore loop control
inc c ; next unit index
djnz prtcomall1 ; loop till done
;
or $FF ; indicate nothing more to do
ret ; finished
;
; Print configuration of serial port
;
prtcom:
; print leader (e.g., "COM0: ")
call crlf
ld de,indent
call prtstr
ld de,strcom
call prtstr
ld a,(unit)
call prtdecb
ld a,':'
call prtchr
ld a,' '
call prtchr
;
ld a,(comatr) ; get attribute byte
bit 7,a ; 0=RS232, 1=terminal
jr z,prtcom1 ; handle serial port configuration
;
; this is a terminal, just say so
ld de,strterm ; point to string
call prtstr ; print it
ret ; and return
;
prtcom1:
ld de,(comcfg) ; load config to DE
;
; print baud rate
push de ; save it
ld a,d ; baud rate is in D
and $1F ; ... bits 4-0
ld l,a ; move to L
ld h,0 ; setup H for decode routine
ld de,75 ; set DE to baud rate decode constant
call decode ; decode baud rate, DE:HL := baud rate
ld bc,bcdtmp ; point to temp bcd buffer
call bin2bcd ; convert baud to BCD
call prtbcd ; and print in decimal
pop de ; restore line characteristics
;
; print parity
ld a,',' ; A := comma
call prtchr ; ... print it
ld a,e ; E has parity config
rrca ; isolate bits 5-3
rrca ; ...
rrca ; ...
and $07 ; ...
ld hl,parmap ; HL := start of parity char table
call addhl ; index into table
ld a,(hl) ; get resulting parity char
call prtchr ; and print
;
; print data bits
ld a,',' ; A := comma
call prtchr ; ... print it
ld a,e ; E has data bits config
and $03 ; isloate bits 1-0
add A,'5' ; convert to printable char
call prtchr ; and print it
;
; print stop bits
ld a,',' ; A := comma
call prtchr ; ... print it
ld a,e ; E has stop bits config
rrca ; isolate bit 2
rrca ; ...
and $01 ; ...
add A,'1' ; convert to printable char
call prtchr ; and print it
;
ret
;
; Load serial device info for specific unit
;
ldcom:
ld a,(unamod) ; get UNA flag
or a ; set flags
jr nz,ldcomu ; go to UNA variant
;
; get device type info
ld a,(unit) ; get unit
ld b,bf_ciodevice ; BIOS device call
ld c,a ; ... and put in C
rst 08 ; call HBIOS, C := attributes
ret nz ; return on error
ld a,c ; attributes to A
ld (comatr),a ; save it
;
; get serial port config
ld b,bf_cioquery ; BIOS serial device query
ld a,(unit) ; get device unit num
ld c,a ; ... and put in C
rst 08 ; call H/UBIOS, DE := line characteristics
ret nz ; abort on error
ld (comcfg),de ; save config
;
xor a ; success
ret
;
ldcomu: ; UNA variant
xor a ; assume attribtues zero
ld (comatr),a ; save it
; get device info
ld a,(unit) ; get unit
ld b,a ; put unit in B
ld c,$18 ; UNA Get line/driver info func
rst 08 ; call H/UBIOS, DE := line characteristics
ld a,c
or a
jr z,ldcomu1
cp $43 ; $43 is OK for now (tell John about this)
jr z,ldcomu1
ret ; return w/ NZ indicating error
;
ldcomu1:
ld (comcfg),de ; save config
;
xor a ; success
ret
;
; Handle special options
;
option:
;
inc ix ; next char
ld a,(ix) ; get it
cp '?' ; is it a '?' as expected?
jp z,usage ; yes, display usage
; cp 'L' ; is it a 'L', display device list?
; jp z,devlist ; yes, display device list
jp errprm ; anything else is an error
;
; Display usage
;
usage:
;
call crlf ; formatting
ld de,msgban1 ; point to version message part 1
call prtstr ; print it
ld a,(unamod) ; get UNA flag
or a ; set flags
ld de,msghb ; point to HBIOS mode message
call z,prtstr ; if not UNA, say so
ld de,msgub ; point to UBIOS mode message
call nz,prtstr ; if UNA, say so
call crlf ; formatting
ld de,msgban2 ; point to version message part 2
call prtstr ; print it
call crlf2 ; blank line
ld de,msguse ; point to usage message
call prtstr ; print it
or $FF ; signal no action performed
ret ; and return
;
; Print character in A without destroying any registers
;
prtchr:
push bc ; save registers
push de
push hl
ld e,a ; character to print in E
ld c,$02 ; BDOS function to output a character
call bdos ; do it
pop hl ; restore registers
pop de
pop bc
ret
;
prtdot:
;
; shortcut to print a dot preserving all regs
push af ; save af
ld a,'.' ; load dot char
call prtchr ; print it
pop af ; restore af
ret ; done
;
; Print a zero terminated string at (DE) without destroying any registers
;
prtstr:
push de
;
prtstr1:
ld a,(de) ; get next char
or a
jr z,prtstr2
call prtchr
inc de
jr prtstr1
;
prtstr2:
pop de ; restore registers
ret
;
; Print the value in A in hex without destroying any registers
;
prthex:
push af ; save AF
push de ; save DE
call hexascii ; convert value in A to hex chars in DE
ld a,d ; get the high order hex char
call prtchr ; print it
ld a,e ; get the low order hex char
call prtchr ; print it
pop de ; restore DE
pop af ; restore AF
ret ; done
;
; print the hex word value in bc
;
prthexword:
push af
ld a,b
call prthex
ld a,c
call prthex
pop af
ret
;
; print the hex dword value in de:hl
;
prthex32:
push bc
push de
pop bc
call prthexword
push hl
pop bc
call prthexword
pop bc
ret
;
; Convert binary value in A to ascii hex characters in DE
;
hexascii:
ld d,a ; save A in D
call hexconv ; convert low nibble of A to hex
ld e,a ; save it in E
ld a,d ; get original value back
rlca ; rotate high order nibble to low bits
rlca
rlca
rlca
call hexconv ; convert nibble
ld d,a ; save it in D
ret ; done
;
; Convert low nibble of A to ascii hex
;
hexconv:
and $0F ; low nibble only
add a,$90
daa
adc a,$40
daa
ret
;
; Print value of A or HL in decimal with leading zero suppression
; Use prtdecb for A or prtdecw for HL
;
prtdecb:
push hl
ld h,0
ld l,a
call prtdecw ; print it
pop hl
ret
;
prtdecw:
push af
push bc
push de
push hl
call prtdec0
pop hl
pop de
pop bc
pop af
ret
;
prtdec0:
ld e,'0'
ld bc,-10000
call prtdec1
ld bc,-1000
call prtdec1
ld bc,-100
call prtdec1
ld c,-10
call prtdec1
ld e,0
ld c,-1
prtdec1:
ld a,'0' - 1
prtdec2:
inc a
add hl,bc
jr c,prtdec2
sbc hl,bc
cp e
ret z
ld e,0
call prtchr
ret
;
; Start a new line
;
crlf2:
call crlf ; two of them
crlf:
push af ; preserve AF
ld a,13 ; <CR>
call prtchr ; print it
ld a,10 ; <LF>
call prtchr ; print it
pop af ; restore AF
ret
;
; Get the next non-blank character from (HL).
;
nonblank:
ld a,(ix) ; load next character
or a ; string ends with a null
ret z ; if null, return pointing to null
cp ' ' ; check for blank
ret nz ; return if not blank
inc ix ; if blank, increment character pointer
jr nonblank ; and loop
;
; Get alpha chars and save in tmpstr
; Length of string returned in A
;
getalpha:
;
ld hl,tmpstr ; location to save chars
ld b,8 ; length counter (tmpstr max chars)
ld c,0 ; init character counter
;
getalpha1:
ld a,(ix) ; get active char
call ucase ; lower case -> uppper case, if needed
cp 'A' ; check for start of alpha range
jr c,getalpha2 ; not alpha, get out
cp 'Z' + 1 ; check for end of alpha range
jr nc,getalpha2 ; not alpha, get out
; handle alpha char
ld (hl),a ; save it
inc c ; bump char count
inc hl ; inc string pointer
inc ix ; increment buffer ptr
djnz getalpha1 ; if space, loop for more chars
;
getalpha2: ; non-alpha, clean up and return
ld (hl),0 ; terminate string
ld a,c ; string length to A
or a ; set flags
ret ; and return
;
; Get numeric chars and convert to number returned in A
; Carry flag set on overflow
;
getnum:
ld c,0 ; C is working register
getnum1:
ld a,(ix) ; get the active char
cp '0' ; compare to ascii '0'
jr c,getnum2 ; abort if below
cp '9' + 1 ; compare to ascii '9'
jr nc,getnum2 ; abort if above
;
; valid digit, add new digit to C
ld a,c ; get working value to A
rlca ; multiply by 10
ret c ; overflow, return with carry set
rlca ; ...
ret c ; overflow, return with carry set
add a,c ; ...
ret c ; overflow, return with carry set
rlca ; ...
ret c ; overflow, return with carry set
ld c,a ; back to C
ld a,(ix) ; get new digit
sub '0' ; make binary
add a,c ; add in working value
ret c ; overflow, return with carry set
ld c,a ; back to C
;
inc ix ; bump to next char
jr getnum1 ; loop
;
getnum2: ; return result
ld a,c ; return result in A
or a ; with flags set, CF is cleared
ret
;
; Get numeric chars and convert to 32-bit number returned in DE:HL
; Carry flag set on overflow
;
getnum32:
ld de,0 ; Initialize DE:HL
ld hl,0 ; ... to zero
getnum32a:
ld a,(ix) ; get the active char
cp '0' ; compare to ascii '0'
jr c,getnum32c ; abort if below
cp '9' + 1 ; compare to ascii '9'
jr nc,getnum32c ; abort if above
;
; valid digit, multiply DE:HL by 10
; X * 10 = (((x * 2 * 2) + x)) * 2
push de
push hl
;
call getnum32e ; DE:HL *= 2
jr c,getnum32d ; if overflow, ret w/ CF & stack pop
;
call getnum32e ; DE:HL *= 2
jr c,getnum32d ; if overflow, ret w/ CF & stack pop
;
pop bc ; DE:HL += X
add hl,bc
ex de,hl
pop bc
adc hl,bc
ex de,hl
ret c ; if overflow, ret w/ CF
;
call getnum32e ; DE:HL *= 2
ret c ; if overflow, ret w/ CF
;
; now add in new digit
ld a,(ix) ; get the active char
sub '0' ; make it binary
add a,l ; add to L, CF updated
ld l,a ; back to L
jr nc,getnum32b ; if no carry, done
inc h ; otherwise, bump H
jr nz,getnum32b ; if no overflow, done
inc e ; otherwise, bump E
jr nz,getnum32b ; if no overflow, done
inc d ; otherwise, bump D
jr nz,getnum32b ; if no overflow, done
scf ; set carry flag to indicate overflow
ret ; and return
;
getnum32b:
inc ix ; bump to next char
jr getnum32a ; loop
;
getnum32c:
; successful completion
xor a ; clear flags
ret ; and return
;
getnum32d:
; special overflow exit with stack fixup
pop hl ; burn 2
pop hl ; ... stack entries
ret ; and return
;
getnum32e:
; DE:HL := DE:HL * 2
sla l
rl h
rl e
rl d
ret
;
; Compare null terminated strings at HL & DE
; If equal return with Z set, else NZ
;
strcmp:
ld a,(de) ; get current source char
cp (hl) ; compare to current dest char
ret nz ; compare failed, return with NZ
or a ; set flags
ret z ; end of string, match, return with Z set
inc de ; point to next char in source
inc hl ; point to next char in dest
jr strcmp ; loop till done
;
; Convert character in A to uppercase
;
ucase:
cp 'a' ; if below 'a'
ret c ; ... do nothing and return
cp 'z' + 1 ; if above 'z'
ret nc ; ... do nothing and return
res 5,a ; clear bit 5 to make lower case -> upper case
ret ; and return
;
; Add the value in A to HL (HL := HL + A)
;
addhl:
add a,l ; A := A + L
ld l,a ; Put result back in L
ret nc ; if no carry, we are done
inc h ; if carry, increment H
ret ; and return
;
; Integer divide DE:HL by C
; result in DE:HL, remainder in A
; clobbers F, B
;
div32x8:
xor a
ld b,32
div32x8a:
add hl,hl
rl e
rl d
rla
cp c
jr c,div32x8b
sub c
inc l
div32x8b:
djnz div32x8a
ret
;
; Jump indirect to address in HL
;
jphl:
jp (hl)
;
; Errors
;
erruse: ; command usage error (syntax)
ld de,msguse
jr err
;
errprm: ; command parameter error (syntax)
ld de,msgprm
jr err
;
errinv: ; invalid HBIOS, signature not found
ld de,msginv
jr err
;
errver: ; unsupported HBIOS version
ld de,msgver
jr err
;
errdev: ; invalid device name
ld de,msgdev
jr err
;
errnum: ; invalid number parsed, overflow
ld de,msgnum
jr err
;
errunt: ; Invalid device unit specified
ld de,msgunt
jr err
;
errcfg: ; Invalid device configuration specified
ld de,msgcfg
jr err
;
err: ; print error string and return error signal
call crlf2 ; print newline
;
err1: ; without the leading crlf
call prtstr ; print error string
;
err2: ; without the string
; call crlf ; print newline
or $FF ; signal error
ret ; done
;
;===============================================================================
; Utility modules
;===============================================================================
;
#include "Encode.asm"
#include "Decode.asm"
#include "bcd.asm"
;
;===============================================================================
; Storage Section
;===============================================================================
;
;
bioloc .dw 0 ; CBIOS starting address
unit .db 0 ; source unit
;
unamod .db 0 ; $FF indicates UNA UBIOS active
;
tmpstr .fill 9,0 ; temporary string of up to 8 chars, zero term
bcdtmp .fill 5,0 ; temporary bcd number storage
;
comcnt .db 0 ; count of com ports
comatr .db 0 ; com port attributes
comcfg .dw 0 ; com port configuration
;
parmap .db "NONENMNS" ; parity character lookup table
;
pflag .db 0 ; $FF indicates prompt option set
;
strcom .db "COM",0 ; serial device name string
strterm .db "VDU",0 ; terminal device string
;
stksav .dw 0 ; stack pointer saved at start
.fill stksiz,0 ; stack
stack .equ $ ; stack top
;
; Messages
;
indent .db " ",0
msgban1 .db "MODE v1.2, 24-Jul-2018",0
msghb .db " [HBIOS]",0
msgub .db " [UBIOS]",0
msgban2 .db "Copyright (C) 2017, Wayne Warthen, GNU GPL v3",0
msguse .db "Usage: MODE COM<n>: [<baud>[,<parity>[,<databits>[,<stopbits>]]]] [/P]",13,10
.db " ex. MODE /? (display version and usage)",13,10
.db " MODE (display config of all serial ports)",13,10
.db " MODE COM0: (display serial unit 0 config)",13,10
.db " MODE COM1: 9600,N,8,1 (set serial unit 1 config)",0
msgprm .db "Parameter error (MODE /? for usage)",0
msginv .db "Invalid BIOS (signature missing)",0
msgver .db "Unexpected HBIOS version",0
msgdev .db "Invalid device name",0
msgnum .db "Unit or slice number invalid",0
msgunt .db "Invalid device unit number specified",0
msgcfg .db "Invalid device configuration specified",0
msgpmt .db "Prepare line then press <return>",0
;
.end