mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 22:43:15 -06:00
* 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 commitad80432252. * Revert "Update romldr.asm" This reverts commit4a9825cd57. * Revert "CP/M 3 Date Hack" This reverts commit153b494e61. * Revert "New ROMLDR and INTRTC driver" This reverts commitd9bed4563e. * 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>
731 lines
18 KiB
Z80 Assembly
731 lines
18 KiB
Z80 Assembly
title 'Boot loader module for CP/M 3.0'
|
|
|
|
maclib options.lib
|
|
|
|
public ?init,?ldccp,?rlccp,?time
|
|
public @bootdu,@bootsl
|
|
extrn ?pmsg,?conin
|
|
extrn ?mvinit,?bnkxlt,?xmove,?move
|
|
extrn @civec,@covec,@aivec,@aovec,@lovec
|
|
extrn @cbnk,?bnksl,?bank
|
|
extrn @sysdr,@ccpdr
|
|
extrn dph0
|
|
extrn @dtbl,@ctbl
|
|
extrn @date,@hour,@min,@sec
|
|
extrn @srch1
|
|
extrn @hbbio
|
|
extrn addhla, bcd2bin, bin2bcd
|
|
extrn cout, phex8, phex16, crlf, crlf2
|
|
|
|
include c:ver.lib
|
|
|
|
bdos equ 5
|
|
|
|
if banked
|
|
tpa$bank equ 1
|
|
else
|
|
tpa$bank equ 0
|
|
endif
|
|
|
|
dseg ; init done from banked memory
|
|
|
|
?init:
|
|
call ?mvinit
|
|
|
|
; Install RomWBW CBIOS stamp in page zero
|
|
ld hl,stpimg
|
|
ld de,stploc
|
|
ld bc,stpsiz
|
|
ldir
|
|
|
|
if banked
|
|
|
|
; Clone page zero from bank 0 to additional banks
|
|
ld b,3 ; last bank
|
|
ld c,0 ; src bank
|
|
init$2:
|
|
push bc ; save bank id's
|
|
call ?xmove ; set src/dest banks
|
|
ld bc,0100h ; size is one page
|
|
ld hl,0 ; dest adr is 0
|
|
ld de,0 ; src adr is 0
|
|
call ?move ; do it
|
|
pop bc ; restore bank id's
|
|
djnz init$2 ; loop till done
|
|
|
|
endif
|
|
|
|
call cinit ; char device init
|
|
ld hl,signon$msg ; signon message
|
|
call ?pmsg ; print it
|
|
|
|
; Get boot disk unit and save it
|
|
ld bc,0F8E0h ; HBIOS func: get boot info
|
|
rst 08 ; do it, D := boot unit, E: := boot slice
|
|
ld a,d ; move boot unit to A
|
|
ld (@bootdu),a ; save it
|
|
ld a,e ; move boot slice to A
|
|
ld (@bootsl),a ; save it
|
|
|
|
call dinit
|
|
call clrram
|
|
ret
|
|
|
|
cinit:
|
|
; Setup CON: I/O vector based on HBIOS console device
|
|
ld b,0FAh ; HBIOS Peek Function
|
|
ld a,(@hbbio) ; HBIOS bank id
|
|
ld d,a ; ... goes in D
|
|
ld hl,112h ; Offset 112h is current console device
|
|
rst 08 ; Call HBIOS, value in E
|
|
push de ; save console unit value
|
|
ld b,e ; Use as loop counter
|
|
inc b ; ... but loop 1 extra time
|
|
ld hl,0 ; Clear vector bitmap
|
|
scf ; Set carry
|
|
cinit$1:
|
|
rr h ; Rotate carry flag
|
|
rr l ; ... into correct vector position
|
|
djnz cinit$1 ; loop as needed
|
|
|
|
ld (@civec),hl ; assign to console input
|
|
ld (@covec),hl ; assign to console output
|
|
|
|
; Setup AUX: I/O vector if there are 2+ char devices in system
|
|
ld bc,0F800h ; HBIOS GET Character Device Count
|
|
rst 08 ; do it, count in E
|
|
ld a,e ; device count to accum
|
|
pop de ; recover console unit num to E
|
|
push af ; save device count
|
|
cp 2 ; check for 2+ char devices
|
|
jr c,cinit$3 ; if not, skip aux assignment
|
|
ld a,e ; console unit num to A
|
|
or a ; check for zero
|
|
ld hl,4000h ; assume aux on second char device
|
|
jr z,cinit$2 ; if console on unit 0, assumption good
|
|
ld hl,8000h ; otherwise, aux goes to first char device
|
|
cinit$2:
|
|
ld (@aivec),hl ; assign to aux input
|
|
ld (@aovec),hl ; assign to aux output
|
|
cinit$3:
|
|
pop af ; recover device count
|
|
; Truncate char table based on actual num of char devices
|
|
rlca ; A still has char device count
|
|
rlca ; * 8 for ctbl entry size
|
|
rlca ; "
|
|
ld hl,@ctbl ; Start of char table
|
|
call addhla ; Skip used entries
|
|
xor a ; Zero to accum
|
|
ld (hl),0 ; Set table terminator
|
|
ret ; done
|
|
|
|
dinit:
|
|
; loop through all disk devices to count hard disk units
|
|
ld b,0F8h ; SYS GET
|
|
ld c,010h ; Disk Drive Unit Count
|
|
rst 08 ; e := disk unit count
|
|
ld b,e ; count to b
|
|
ld a,b ; count to a
|
|
or a ; set flags
|
|
ret z ; !!! handle zero devices (albeit poorly) !!!
|
|
|
|
; loop thru devices to count total hard disk volumes
|
|
ld c,0 ; init c as device list index
|
|
ld d,0 ; init d as total device count
|
|
ld e,0 ; init e for hard disk device count
|
|
ld hl,drvlst ; init hl ptr to drive list
|
|
;
|
|
dinit2:
|
|
call dinit3 ; check drive
|
|
inc c ; next unit
|
|
djnz dinit2 ; loop
|
|
ld a,d ; total device count to d
|
|
ld (drvlstc),a ; save the count
|
|
jr dinit4 ; continue
|
|
|
|
dinit3:
|
|
push de ; save de (hard disk volume counter)
|
|
push hl ; save drive list ptr
|
|
push bc ; save loop control
|
|
ld b,17h ; hbios func: report device info
|
|
rst 08 ; call hbios, unit to c
|
|
ld a,d ; device type to a
|
|
pop bc ; restore loop control
|
|
pop hl ; restore drive list ptr
|
|
pop de ; restore de
|
|
cp 30h ; hard disk device?
|
|
jr nc,dinit3a ; if so, handle special
|
|
ld (hl),c ; save unit num in list
|
|
inc hl ; bump ptr
|
|
inc d ; inc total device count
|
|
ret
|
|
;
|
|
dinit3a:
|
|
; check for active and return if not
|
|
push de ; save de (hard disk volume counter)
|
|
push hl ; save drive list ptr
|
|
push bc ; save loop control
|
|
|
|
ld b,18h ; hbios func: sense media
|
|
ld e,1 ; perform media discovery
|
|
rst 08
|
|
|
|
pop bc ; restore loop control
|
|
pop hl ; restore drive list ptr
|
|
pop de ; restore de
|
|
|
|
ret nz ; if no media, just return
|
|
|
|
; if active...
|
|
ld (hl),c ; save unit num in list
|
|
inc hl ; bump ptr
|
|
inc d ; inc total device count
|
|
inc e ; increment hard disk count
|
|
ret ; and return
|
|
|
|
dinit4: ; set slices per volume (hdspv) based on hard disk volume count
|
|
ld a,e ; hard disk volume count to a
|
|
ld e,8 ; assume 8 slices per volume
|
|
dec a ; dec accum to check for count = 1
|
|
jr z,dinit5 ; yes, skip ahead to implement 8 hdspv
|
|
ld e,4 ; now assume 4 slices per volume
|
|
dec a ; dec accum to check for count = 2
|
|
jr z,dinit5 ; yes, skip ahead to implement 4 hdspv
|
|
ld e,2 ; in all other cases, we use 2 hdspv
|
|
|
|
dinit5:
|
|
ld a,e ; slices per volume value to accum
|
|
ld (hdspv),a ; save it
|
|
ld hl,0 ; dph index
|
|
|
|
ld a,(@bootdu) ; boot disk unit
|
|
ld d,a ; ... to d
|
|
ld a,(@bootsl) ; boot slice
|
|
ld e,a ; ... to e
|
|
ld b,1 ; one slice please
|
|
call dinit8a ; make DPH for A:
|
|
|
|
ld a,(drvlstc) ; active drive list count to accum
|
|
ld b,a ; ... and move to b for loop counter
|
|
ld de,drvlst ; de is ptr to active drive list
|
|
|
|
dinit6:
|
|
; loop thru all units available
|
|
push de ; preserve drive list ptr
|
|
ex de,hl ; list ptr to hl
|
|
ld c,(hl) ; get unit num from list
|
|
ex de,hl ; list ptr back to de
|
|
push bc ; preserve loop control
|
|
push hl ; preserve dph pointer
|
|
ld b,17h ; hbios func: report device info
|
|
rst 08 ; call hbios, d := device type
|
|
pop hl ; restore dph pointer
|
|
pop bc ; get unit index back in c
|
|
push bc ; resave loop control
|
|
call dinit7 ; make drive map entry(s)
|
|
pop bc ; restore loop control
|
|
inc c ; increment list index
|
|
pop de ; restore drive list ptr
|
|
inc de ; increment active drive list ptr
|
|
djnz dinit6 ; loop as needed
|
|
|
|
; zero out remaining dph table entries
|
|
ld a,16 ; dph table entries
|
|
sub l ; subtract entries used
|
|
ret z ; return if all entries used
|
|
ld b,a ; save as loop counter
|
|
ld a,l ; current dph to accum
|
|
rlca ; *2 for word entry
|
|
ld hl,@dtbl ; start of dtbl
|
|
call addhla ; hl now points to entry
|
|
|
|
dinit6a:
|
|
xor a ; zero accum
|
|
ld (hl),a ; zero lsb
|
|
inc hl ; next byte
|
|
ld (hl),a ; zero msb
|
|
inc hl ; next byte
|
|
djnz dinit6a
|
|
ret ; finished
|
|
|
|
dinit7: ; process a unit (all slices)
|
|
ld e,0 ; initialize slice index
|
|
ld b,1 ; default loop counter
|
|
ld a,d ; device type to accum
|
|
ld d,c ; unit number to d
|
|
cp 030h ; hard disk device?
|
|
jr c,dinit8 ; nope, leave loop count at 1
|
|
ld a,(hdspv) ; get slices per volume to accum
|
|
ld b,a ; move to b for loop counter
|
|
|
|
dinit8: ; test to avoid reallocating boot disk unit/slice
|
|
ld a,(@bootdu) ; boot disk unit to accum
|
|
cp d ; compare to cur unit
|
|
jr nz,dinit8a ; if ne, ok to continue
|
|
ld a,(@bootsl) ; boot slice to accum
|
|
cp e ; compare to cur slice
|
|
jr nz,dinit8a ; if ne, ok to continue
|
|
inc e ; is boot du/slice, skip it
|
|
djnz dinit8 ; loop till done with unit
|
|
ret
|
|
|
|
dinit8a:
|
|
; d=unit, e=slice, l=dph#, b=slice cnt
|
|
ld a,l ; dph # to accum
|
|
cp 16 ; dph table size
|
|
ret z ; bail out if overflow
|
|
push hl ; save dph #
|
|
rlca ; *2 for adr entry
|
|
ld hl,@dtbl ; dph table start
|
|
call addhla ; offset hl to desired entry
|
|
ld a,(hl) ; dereference
|
|
inc hl
|
|
ld h,(hl)
|
|
ld l,a
|
|
dec hl ; backup to slice field
|
|
ld (hl),e ; update slice number
|
|
dec hl ; backup to unit number
|
|
ld (hl),d ; update unit number
|
|
pop hl ; restore dph #
|
|
inc hl ; next dph #
|
|
inc e ; next slice
|
|
djnz dinit8 ; loop till done with unit
|
|
ret
|
|
|
|
; RomWBW CBIOS page zero stamp starts at $40
|
|
; $40-$41: Marker ('W', ~'W')
|
|
; $42-$43: Version bytes: major/minor, update/patch
|
|
; $44-$45: CBIOS Extension Info address
|
|
|
|
stploc equ 40h
|
|
stpimg db 'W',~'W' ; marker
|
|
db rmj << 4 | rmn ; first byte of version info
|
|
db rup << 4 | rtp ; second byte of version info
|
|
dw cbx ; address of cbios ext data
|
|
stpsiz equ $ - stpimg
|
|
|
|
|
|
cseg ; ram disk init must be done from resident memory
|
|
|
|
;
|
|
; Initialize ram disk by filling directory with 'e5' bytes
|
|
; Fill first 8k of ram disk track 1 with 'e5'
|
|
;
|
|
clrram:
|
|
di ; no interrupts
|
|
ld a,(0FFE0h) ; get current bank
|
|
push af ; save it
|
|
;ld a,(bnkramd) ; first bank of ram disk
|
|
ld a,080h ; first bank of ram disk
|
|
;call hb_bnksel ; select bank
|
|
call 0FFF3h ; select bank
|
|
|
|
; Check first 32 directory entries. If any start with an invalid
|
|
; value, init the ram disk. Valid entries are e5 (empty entry) or
|
|
; 0-15 (user number).
|
|
ld hl,0
|
|
ld de,32
|
|
ld b,32
|
|
clrram0:
|
|
ld a,(hl)
|
|
cp 0E5h
|
|
jr z,clrram1 ; e5 is valid
|
|
cp 16
|
|
jr c,clrram1 ; 0-15 is also valid
|
|
jr clrram2 ; invalid entry! jump to init
|
|
clrram1:
|
|
add hl,de ; loop for 32 entries
|
|
djnz clrram0
|
|
; jr clrram2 ; *debug*
|
|
jr clrram3 ; all entries valid, bypass init
|
|
clrram2:
|
|
ld hl,0 ; source adr for fill
|
|
ld bc,2000h ; length of fill is 8k
|
|
ld a,0E5h ; fill value
|
|
call fill ; do it
|
|
or 0ffh ; flag value for cleared
|
|
ld (clrflg),a ; save it
|
|
clrram3:
|
|
;ld a,(bnkuser) ; usr bank (tpa)
|
|
pop af ; recover original bank
|
|
;call hb_bnksel ; select bank
|
|
call 0FFF3h ; select bank
|
|
ei ; resume interrupts
|
|
|
|
ld a,(clrflg) ; get cleared flag
|
|
or a ; set flags
|
|
ld hl,clr$msg ; clear ram disk message
|
|
call nz,?pmsg ; print msg if true
|
|
|
|
ret
|
|
|
|
;
|
|
; Fill memory at hl with value a, length in bc. All regs used.
|
|
; Length *must* be greater than 1 for proper operation!!!
|
|
;
|
|
fill:
|
|
ld d,h ; set de to hl
|
|
ld e,l ; so destination equals source
|
|
ld (hl),a ; fill the first byte with desired value
|
|
inc de ; increment destination
|
|
dec bc ; decrement the count
|
|
ldir ; do the rest
|
|
ret ; return
|
|
|
|
|
|
cseg ; boot loading most be done from resident memory
|
|
|
|
; This version of the boot loader loads the CCP from a file
|
|
; called CCP.COM on the system drive.
|
|
|
|
?ldccp:
|
|
; Force CCP to use system boot drive as initial default
|
|
ld a,(@sysdr) ; get system boot drive
|
|
ld (@ccpdr),a ; set CCP current drive
|
|
|
|
; First time, load the CCP.COM file into TPA
|
|
ld a,(@sysdr) ; get system boot drive
|
|
;ld (4),a ; save in page zero???
|
|
inc a ; drive + 1 for FCB
|
|
ld (ccp$fcb),a ; stuff into FCB
|
|
add 'A' - 1 ; drive letter
|
|
ld (ccp$msg$drv),a ; save for load msg
|
|
xor a
|
|
ld (ccp$fcb+15),a
|
|
ld hl,0
|
|
ld (fcb$nr),hl
|
|
ld de,ccp$fcb
|
|
call open
|
|
inc a
|
|
jr z,no$CCP
|
|
ld de,0100H
|
|
call setdma
|
|
ld de,128
|
|
call setmulti
|
|
ld de,ccp$fcb
|
|
call read
|
|
|
|
if banked
|
|
|
|
ld hl,0100h ; clone 3K, just in case
|
|
ld bc,0C80h
|
|
ld a,(@cbnk) ; save current bank
|
|
push af
|
|
ld$1:
|
|
ld a,tpa$bank ; select TPA
|
|
call ?bnksl
|
|
ld a,(hl) ; get a byte
|
|
push af
|
|
ld a,2 ; select extra bank
|
|
call ?bnksl
|
|
pop af ; save the byte
|
|
ld (hl),a
|
|
inc hl ; bump pointer, drop count
|
|
dec bc
|
|
ld a,b ; test for done
|
|
or c
|
|
jr nz,ld$1
|
|
pop af ; restore original bank
|
|
call ?bnksl
|
|
|
|
endif
|
|
|
|
ret
|
|
|
|
no$CCP: ; here if we couldn't find the file
|
|
ld hl,ccp$msg
|
|
call ?pmsg
|
|
call ?conin
|
|
jp ?ldccp
|
|
|
|
|
|
?rlccp:
|
|
|
|
if banked
|
|
|
|
ld hl,0100h ; clone 3K
|
|
ld bc,0C80h
|
|
rl$1:
|
|
ld a,2 ; select extra bank
|
|
call ?bnksl
|
|
ld a,(hl) ; get a byte
|
|
push af
|
|
ld a,tpa$bank ; select TPA
|
|
call ?bnksl
|
|
pop af ; save the byte
|
|
ld (hl),a
|
|
inc hl ; bump pointer, drop count
|
|
dec bc
|
|
ld a,b ; test for done
|
|
or c
|
|
jr nz,rl$1
|
|
ret
|
|
|
|
else
|
|
|
|
jr ?ldccp
|
|
|
|
endif
|
|
|
|
?time:
|
|
; per CP/M 3 docs, *must* preserve HL, DE
|
|
push hl
|
|
push de
|
|
|
|
; force return through time$ret
|
|
ld hl,time$ret
|
|
push hl
|
|
|
|
; branch to get or set routine
|
|
ld a,c ; get switch value
|
|
or a ; test for zero
|
|
jr z,time$get ; 0 means get time
|
|
jr time$set ; else set time
|
|
|
|
time$ret:
|
|
; restore HL, DE
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
time$get:
|
|
; RTC -> cpm date/time in SCB
|
|
|
|
; read time from RTC
|
|
ld b,020h ; HBIOS func: get time
|
|
ld hl,tim$buf ; time buffer
|
|
rst 08 ; do it
|
|
ret nz ; bail out on error
|
|
|
|
ld a,(datehack)
|
|
or a
|
|
jr nz,time$get1
|
|
|
|
; convert yymmss in time buffer -> cpm3 epoch date offset
|
|
call date2cpm ; time buf (yr, mon, day) -> SCB (@date)
|
|
|
|
time$get1:
|
|
; set time fields in SCB
|
|
ld a,(tim$hr) ; get hour from time buf
|
|
ld (@hour),a ; ... and put in SCB
|
|
ld a,(tim$min) ; get minute from time buf
|
|
ld (@min),a ; ... and put in SCB
|
|
ld a,(tim$sec) ; get second from time buf
|
|
ld (@sec),a ; ... and put in SCB
|
|
|
|
ret
|
|
|
|
time$set:
|
|
; CPM date/time in SCB -> RTC
|
|
|
|
; convert CPM3 epoch date offset in SCB -> yymmss in time buffer
|
|
;call cpm2date ; SCB (@date) -> time buf (yr, mon, day)
|
|
|
|
; this is a temporary hack!!!
|
|
; since we cannot actually set the date on the RTC, we
|
|
; just read the current RTC date and use that so that we
|
|
; don't clobber a potentially good date.
|
|
; read time from RTC
|
|
ld b,020h ; HBIOS func: get time
|
|
ld hl,tim$buf ; time buffer
|
|
rst 08 ; do it
|
|
ret nz ; bail out on error
|
|
;
|
|
; now we set a hack active flag so that future time$get
|
|
; calls do not update the date field in the SCB
|
|
;
|
|
ld a,0FFh ; true value
|
|
ld (datehack),a ; save it
|
|
|
|
; copy CPM3 time values from SCB -> time buffer
|
|
ld a,(@hour) ; get hour from SCB
|
|
ld (tim$hr),a ; ... and put in tim$hr
|
|
ld a,(@min) ; get minute from SCB
|
|
ld (tim$min),a ; ... and put in tim$min
|
|
ld a,(@sec) ; get second from SCB
|
|
ld (tim$sec),a ; ... and put in tim$sec
|
|
|
|
; send time to RTC
|
|
ld b,021h ; HBIOS func: set time
|
|
ld hl,tim$buf ; ... from time buffer
|
|
rst 08 ; do it
|
|
|
|
ret
|
|
|
|
date2cpm:
|
|
; Convert YYMMSS from time buffer at HL
|
|
; into offset from CPM epoch and store
|
|
; result in SCB.
|
|
|
|
ld hl,0 ; initialize day counter
|
|
; Add in days for elapsed years
|
|
ld a,(tim$yr) ; get current year
|
|
call bcd2bin ; convert to binary
|
|
sub 78 ; epoch year
|
|
jr nc,d2c1 ; if not negative, good to go
|
|
add a,100 ; else, adjust for Y2K wrap
|
|
d2c1:
|
|
ld b,a ; loop counter
|
|
ld c,3 ; leap counter, 78->79->80, so 3
|
|
ld de,365 ; days in non-leap year
|
|
or a ; check for zero
|
|
jr z,d2c10 ; skip if zero
|
|
d2c2:
|
|
add hl,de ; add non-leap days
|
|
dec c ; dec leap counter
|
|
jr nz,d2c3 ; if not leap, bypss leap inc
|
|
inc hl ; add leap day
|
|
ld c,4 ; reset leap year counter
|
|
d2c3:
|
|
djnz d2c2 ; loop for all years
|
|
d2c10:
|
|
; Add in days for elapsed months
|
|
ex de,hl ; save HL in DE
|
|
ld hl,daystbl ; point to table of cum days by month
|
|
ld a,(tim$mon) ; get current month
|
|
call bcd2bin ; convert to binary
|
|
dec a ; index from zero
|
|
rlca ; table entries are 2 bytes
|
|
call addhla ; offset to desired month entry
|
|
ld a,(hl) ; get the entry into HL
|
|
inc hl ; ...
|
|
ld h,(hl) ; ...
|
|
ld l,a ; ...
|
|
ex de,hl ; HL = day count, DE = months count
|
|
add hl,de ; add months count into day count
|
|
; Add leap day for current year if appropriate
|
|
dec c ; C still has leap counter
|
|
jr nz,d2c20 ; skip if not leap year
|
|
ld a,(tim$mon) ; get cur mon
|
|
cp 3 ; March?
|
|
jr c,d2c20 ; skip if mon less than March
|
|
inc hl ; add leap day for cur year
|
|
d2c20:
|
|
; Add in days elapsed within month
|
|
; Note that we don't adjust the date to be a zero
|
|
; offset which seems wrong. From what I can tell
|
|
; the CP/M epoch is really 1/0/1978 rather than the
|
|
; 1/1/1978 that the documentation claims. Below seems
|
|
; to work correctly.
|
|
ld a,(tim$day) ; get day
|
|
call bcd2bin ; make binary
|
|
call addhla ; add in days
|
|
ld (@date),hl ; store in SCB
|
|
ret
|
|
|
|
cpm2date:
|
|
; Convert CPM epoch date offset in SCB
|
|
; into YYMMSS values and store result in
|
|
; time buffer at HL.
|
|
ld a,019h
|
|
ld (tim$yr),a
|
|
ld a,001h
|
|
ld (tim$mon),a
|
|
ld a,001h
|
|
ld (tim$day),a
|
|
|
|
ret
|
|
|
|
daystbl:
|
|
; cumulative days elapsed by month (non-leap year)
|
|
dw 0 ; January
|
|
dw 31 ; February (non-leap)
|
|
dw 59 ; March
|
|
dw 90 ; April
|
|
dw 120 ; May
|
|
dw 151 ; June
|
|
dw 181 ; July
|
|
dw 212 ; August
|
|
dw 243 ; September
|
|
dw 273 ; October
|
|
dw 304 ; November
|
|
dw 334 ; December
|
|
|
|
; RTC time buffer (all values packed bcd)
|
|
tim$buf:
|
|
tim$yr db 80h
|
|
tim$mon db 05h
|
|
tim$day db 10h
|
|
tim$hr db 01h
|
|
tim$min db 02h
|
|
tim$sec db 03h
|
|
|
|
datehack db 00h
|
|
|
|
open:
|
|
ld c,15
|
|
jp bdos
|
|
|
|
setdma:
|
|
ld c,26
|
|
jp bdos
|
|
|
|
setmulti:
|
|
ld c,44
|
|
jp bdos
|
|
|
|
read:
|
|
ld c,20
|
|
jp bdos
|
|
|
|
clrflg db 0 ; RAM disk cleared flag
|
|
clr$msg db 'RAM Disk Initialized',13,10,13,10,0
|
|
|
|
if zpm
|
|
|
|
signon$msg db 13,10,'ZPM3'
|
|
if banked
|
|
db ' [BANKED]'
|
|
endif
|
|
db ' on HBIOS v'
|
|
biosver
|
|
db 13,10,13,10,0
|
|
|
|
ccp$msg db 13,10,'BIOS Err on '
|
|
ccp$msg$drv db '?'
|
|
db ': No ZCCP.COM file',0
|
|
|
|
|
|
ccp$fcb db 0,'ZCCP ','COM',0,0,0,0
|
|
ds 16
|
|
fcb$nr db 0,0,0
|
|
|
|
else
|
|
|
|
signon$msg db 13,10,'CP/M v3.0'
|
|
if banked
|
|
db ' [BANKED]'
|
|
endif
|
|
db ' on HBIOS v'
|
|
biosver
|
|
db 13,10,13,10,0
|
|
|
|
ccp$msg db 13,10,'BIOS Err on '
|
|
ccp$msg$drv db '?'
|
|
db ': No CCP.COM file',0
|
|
|
|
|
|
ccp$fcb db 0,'CCP ','COM',0,0,0,0
|
|
ds 16
|
|
fcb$nr db 0,0,0
|
|
|
|
endif
|
|
|
|
@bootdu db 0 ; boot disk unit
|
|
@bootsl db 0 ; boot slice
|
|
hdspv db 2 ; slices per volume for hard disks (must be >= 1)
|
|
drvlst ds 32 ; active drive list used durint drv_init
|
|
drvlstc db 0 ; entry count for active drive list
|
|
|
|
; The following section contains key information and addresses for the
|
|
; RomWBW CBIOS. A pointer to the start of this section is stored with
|
|
; with the CBX data in page zero at $44 (see above).
|
|
|
|
cbx:
|
|
devmapadr dw 0 ; device map address
|
|
drvtbladr dw @dtbl ; drive map address (filled in later)
|
|
dphtbladr dw dph0 ; dpb map address
|
|
cbxsiz equ $ - cbx
|
|
|
|
end
|