Compare commits
	
		
			50 Commits
		
	
	
		
			59b0fcfa0a
			...
			bios
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ec43c11443 | |||
| e71c23da39 | |||
| e33f6dc6eb | |||
| 22c1f7b0b8 | |||
| aba1a50e0f | |||
| e055d9b300 | |||
| f978834857 | |||
| 0c4055d685 | |||
| 1ebd112da5 | |||
| 23febee616 | |||
| 4e90117d06 | |||
| edd448b006 | |||
| a7a9404bdd | |||
| f227ae6db6 | |||
| c9b665d509 | |||
| 3943b5502a | |||
| f68fa4c0a6 | |||
| d92b8f6ba4 | |||
| 96a5804467 | |||
| 9ab92eb8a5 | |||
| a6a93e656a | |||
| b5cfd501c5 | |||
| 8f615e1bd8 | |||
| 31cf42167f | |||
| a616d47e76 | |||
| 1cd6720bf6 | |||
| 88fcc86e72 | |||
| 6cbb038b42 | |||
| aed8ca28f9 | |||
| 3441aea9c1 | |||
| 893753561c | |||
| eda7b3ac1f | |||
| eafc0ce98e | |||
| d7d8532021 | |||
| 6544321450 | |||
| 98ed74f10d | |||
| 15872f93b9 | |||
| 8c12c2106f | |||
| 35a2f12cce | |||
| dce0719796 | |||
| abeecf4e93 | |||
| 180fc932c9 | |||
| f0104c74c2 | |||
| 18a5615b53 | |||
| 2988fb9059 | |||
| 2b23634bb8 | |||
| 53add429a9 | |||
| a019c37755 | |||
| 6bb29fe7ff | |||
| 853efd9bac | 
| @@ -12,7 +12,7 @@ insert_final_newline = true | ||||
| indent_style = space | ||||
| indent_size = 2 | ||||
|  | ||||
| [*.md] | ||||
| [*.{md,typ}] | ||||
| indent_style = space | ||||
| indent_size = 2 | ||||
| max_line_length = 80 | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,6 +6,9 @@ | ||||
| *.s19 | ||||
| build/ | ||||
| map.txt | ||||
| bbmkhash | ||||
| *.pdf | ||||
|  | ||||
| # Build system generated files | ||||
| src/version.s | ||||
| src/bbhash.s | ||||
|   | ||||
							
								
								
									
										67
									
								
								bbmkhash.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								bbmkhash.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* Generates BUZBEE command hash data table asm file */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| /* Length of commands in printable-char count (excluding NUL terminator). */ | ||||
| const int s_cchCmd = 4; | ||||
|  | ||||
| /* Add your commands here to be hashed. Imprtant that they all be CCH_CMD | ||||
|  * chars long EXCLUDING the NUL terminator. Order is important here. */ | ||||
| const char *s_ppszCmds[] = { | ||||
| 	"CALL", | ||||
| 	"HELP", | ||||
| 	"PEEK", | ||||
| 	"POKE", | ||||
| 	"SREC", | ||||
| 	/* "BOOT", */ | ||||
| }; | ||||
|  | ||||
| int mkHash(const char pszCmd[]); | ||||
|  | ||||
| int main(void) { | ||||
| 	/* Emit file header */ | ||||
| 	puts("; CHIBI PC-09 -- BUZBEE -- Command Hash Table\n\ | ||||
| ; Copyright (c) 2025 Gale Faraday\n\ | ||||
| ; Licensed under MIT\n\ | ||||
| \n\ | ||||
| ; This file generated by bbmkhash.c\n\ | ||||
| \n\ | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\ | ||||
| ;;\n\ | ||||
| ;; BUZBEE Command Hash Table\n\ | ||||
| ;;\n\ | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\ | ||||
| \n\ | ||||
|   SECTION BBHASHES\n\ | ||||
| \n\ | ||||
|   EXPORT BBCHTC\n\ | ||||
|   EXPORT BBCHT\n"); | ||||
|  | ||||
| 	/* Command count. | ||||
| 	* NOTE: This is a u16 because it gets emitted into the output assembly. */ | ||||
| 	uint16_t cCmds = sizeof(s_ppszCmds) / sizeof(char *); | ||||
|  | ||||
| 	/* Emit command count */ | ||||
| 	printf("BBCHTC\n  fdb $%.4X\n", cCmds); | ||||
|  | ||||
| 	/* Emit table data */ | ||||
| 	puts("\nBBCHT"); | ||||
| 	for (int iCmd = 0; iCmd < cCmds; iCmd++) { | ||||
| 		uint8_t uHash = mkHash(s_ppszCmds[iCmd]); | ||||
| 		printf("  fcb $%.2X\n", uHash); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int mkHash(const char pszCmd[]) { | ||||
| 	uint8_t nhash = 0; | ||||
|  | ||||
| 	/* NOTE: Very important that condition is the length of the string MINUS the | ||||
| 	 * NUL terminator, in this case iChar < 4 */ | ||||
| 	for (int iChar = 0; iChar < s_cchCmd; iChar++) | ||||
| 		nhash = nhash - pszCmd[iChar]; | ||||
|  | ||||
| 	return nhash; | ||||
| } | ||||
							
								
								
									
										307
									
								
								docs/firmware.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								docs/firmware.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,307 @@ | ||||
| #set document( | ||||
|   title: "CHIBI PC-09 Firmware Manual", | ||||
|   author: "Gale Faraday", | ||||
|   description: "CHIBI PC-09 Firmware: BIOS, CHIBIO, and BUZBEE documentation", | ||||
| ) | ||||
|  | ||||
| #import "style.typ": conf | ||||
| #show: conf.with( | ||||
|   title: [CHIBI PC-09 Firmware Manual and Technical Reference], | ||||
|   subtitle: [A Complete Firmware Package for the CHIBI PC-09], | ||||
|   author: [Gale Faraday], | ||||
| ) | ||||
|  | ||||
| = Introduction <intro> | ||||
|  | ||||
| This is the complete, stock firmware package for Amber Zeller's CHIBI PC-09 | ||||
| hobby computer. Featuring Gale Faraday's BUZBEE machine language monitor | ||||
| (@bb-intro), the CHIBI/O BIOS interface (@chibio-intro), and several inbuilt | ||||
| programs (@programs). | ||||
|  | ||||
| The CHIBI PC-09 name and platform is copyright 2024-2025 Amber Zeller. The CHIBI | ||||
| PC-09 BIOS is copyright 2024-2025 Gale Faraday and Amber Zeller. BUZBEE is | ||||
| copyright 2025 Gale Faraday. All CHIBI PC-09 components are licensed under the | ||||
| MIT license. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| = Building CHIBI PC-09 Firmware from Source <building> | ||||
|  | ||||
| Building the CHIBI PC-09 firmware from source requires LWTOOLS | ||||
| #link("http://lwtools.ca"), a functioning C compiler (`cc`), and a POSIX Shell | ||||
| implementation (`sh`). The firmware was developed using LWTOOLS version 4.24 on | ||||
| Linux, though later versions may work as well. A GNU Make "makefile" is provided for | ||||
| building on Linux. GNU binutils' `objcopy` is also used to build the compiled | ||||
| Motorola S-Record into a raw binary. Development is tracked using Git. | ||||
|  | ||||
| Using the makefile is simple. It provides facilities for easy building, and | ||||
| development. | ||||
|  | ||||
| To build an S-Record of the ROM run: | ||||
| ```sh | ||||
| make generate && make boot.s19 | ||||
| ``` | ||||
|  | ||||
| To build a ROM image with `objcopy` run: | ||||
| ```sh | ||||
| make generate && make | ||||
| ``` | ||||
|  | ||||
| In order to rebuild, first the generated files and existing objects must be | ||||
| cleaned. To do this a `make clean` pseudo-target is defined. | ||||
|  | ||||
| Building the documentation can also be accomplished using `make docs`, provided | ||||
| `typst` is installed. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| = Programs in ROM <programs> | ||||
|  | ||||
| Some simple programs are included in the CHIBI PC-09's firmware ROM and can be | ||||
| called through BUZBEE's `CALL` command. Soft reseting the CHIBI PC-09 is also | ||||
| handled through this interface by calling `$8000` or the ROM entrypoint. | ||||
|  | ||||
| A simple memory test based on ROBIT-2 for the SWTPC is included at `$9000`. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| = CHIBI/O BIOS Interface <chibio-intro> | ||||
|  | ||||
| #lorem(120) | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| = BUZBEE Machine Language Monitor <bb-intro> | ||||
|  | ||||
| BUZBEE is a "machine language monitor" styled after Steve Wozniak's WOZMON for | ||||
| the CHIBI PC-09 computer platform. It is the stock bootloader and | ||||
| interface for the PC-09. This chapter goes over the usage of BUZBEE, and some of | ||||
| the technical internals of how it works and how to use it. | ||||
|  | ||||
| BUZBEE was created primarily to debug prototype versions of the CHIBI PC-09. | ||||
| BUZBEE will grow alongside the CHIBI PC-09 project. It also functions as a | ||||
| reference implementation of an OS using the CHIBI PC-09 BIOS. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| == BUZBEE Functions <bbfunc> | ||||
|  | ||||
| BUZBEE is at its core a chain loader or bootloader. This means that most of the | ||||
| functionality of the CHIBI starts with using BUZBEE. BUZBEE functions are called | ||||
| _Internal Functions_ or "IFs". These are documented in @bbif-top. BUZBEE | ||||
| functions are native functions mapped to textual commands entered at the BUZBEE | ||||
| prompt. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| == Internal Functions (IFs) <bbif-top> | ||||
|  | ||||
| Internal Functions are the textual commands that BUZBEE interprets from the | ||||
| command line to execute the user's wish. Internal Functions are canonically | ||||
| listed in alphabetical order. Below in @bbif-table is a list of available IFs. | ||||
|  | ||||
| #figure( | ||||
|   table( | ||||
|     columns: (auto, auto, 1fr), | ||||
|     inset: 10pt, | ||||
|     align: center, | ||||
|     fill: (_, y) => | ||||
|       if calc.odd(y) { luma(250) } | ||||
|       else { white }, | ||||
|     table.header( | ||||
|       [*Name* (pg. no.)], [*Command Token*], [*Description*] | ||||
|     ), | ||||
|     [`CALL` (#ref(<bbif-call>, form: "page"))], | ||||
|     [`$00`], | ||||
|     [Call a resident routine in the MPU's address space.], | ||||
|     [`HELP` (#ref(<bbif-help>, form: "page"))], | ||||
|     [`$01`], | ||||
|     [Display a summary of known commands.], | ||||
|     [`PEEK` (#ref(<bbif-peek>, form: "page"))], | ||||
|     [`$02`], | ||||
|     [Dumps memory from the MPU's address space to the terminal.], | ||||
|     [`POKE` (#ref(<bbif-poke>, form: "page"))], | ||||
|     [`$03`], | ||||
|     [Overwrites memory in the MPU's address space.], | ||||
|     [`SREC` (#ref(<bbif-srec>, form: "page"))], | ||||
|     [`$04`], | ||||
|     [Switches into Motorola S-Record receive mode.], | ||||
|   ), | ||||
|   caption: [Table of IFs], | ||||
| ) <bbif-table> | ||||
|  | ||||
| In the following pages these IFs are described in specific. | ||||
|  | ||||
| IFs are tokenized from their textual form into a binary "bytecode" form. This | ||||
| bytecode is described in @bbinternals. | ||||
|  | ||||
| First the text command name (eg. `CALL`) is hashed in some way into a token. | ||||
| Then conditional processing on the remainder of the line occurs. Values given in | ||||
| hex are encoded as their corresponding bytes directly. The token buffer | ||||
| mechanics are described more in @bbinternals. Subcommands are also hashed into | ||||
| tokens. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| // Function for creating IF page headers | ||||
| #let _ifpagehead( | ||||
|   desc: none, | ||||
|   syntax: none, | ||||
|   params: (), | ||||
| ) = { | ||||
|   smallcaps[#desc] | ||||
|   parbreak() | ||||
|   [Syntax: #syntax] | ||||
|   parbreak() | ||||
|   [Parameters: ] | ||||
|   if params.len() > 0 { | ||||
|     for (param, desc) in params [ | ||||
|       - #raw("<" + upper(param) + ">"): #desc | ||||
|     ] | ||||
|   } else { | ||||
|     text(style: "italic")[N/A] | ||||
|   } | ||||
| } | ||||
|  | ||||
| ==== IF: `CALL` <bbif-call> | ||||
|  | ||||
| #_ifpagehead( | ||||
|   desc: "Calls a resident routine in the MPU's address space.", | ||||
|   syntax: [`CALL <PTR>`], | ||||
|   params: ( | ||||
|     ptr: "An absolute pointer to a position in the 6309 MPU's memory map.", | ||||
|   ), | ||||
| ) | ||||
|  | ||||
| Call takes an absolute pointer into the MPU's address space to call as if it | ||||
| were a subroutine using `JSR`. | ||||
|  | ||||
| // TODO: For when CHIBI PC-09 Prototype #2 comes out or whenever we get banking | ||||
| // add it here "Special care must be taken to properly bank in the correct | ||||
| // memory banks before executing this command." yadda yadda | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| ==== IF: `HELP` <bbif-help> | ||||
|  | ||||
| #_ifpagehead( | ||||
|   desc: "Displays a summary of available IFs.", | ||||
|   syntax: [`HELP`], | ||||
|   params: () | ||||
| ) | ||||
|  | ||||
| `HELP` does what it says on the tin. It should be noted that between Git tags of | ||||
| the firmware the message displayed by this may be incomplete or innaccurate. | ||||
| Internally all this does is print a string with the UART using the `POUTZSTR` | ||||
| BIOS routine. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| ==== IF: `PEEK` <bbif-peek> | ||||
|  | ||||
| #_ifpagehead( | ||||
|   desc: "Dumps memory from the MPU's address space to the terminal.", | ||||
|   syntax: [`PEEK <BASE> [<HIGH>]`], | ||||
|   params: ( | ||||
|     base: [ | ||||
|       The address (two bytes) of the byte to dump or the base (lower bound) | ||||
|       address of the byte to start dumping from if `<HIGH>` is specified. | ||||
|     ], | ||||
|     high: [ | ||||
|       An optional operand given as the upper bound of the range to dump. Forms | ||||
|       a range together with `<BASE>`. (two bytes) | ||||
|     ], | ||||
|   ) | ||||
| ) | ||||
|  | ||||
| Peeking memory causes the MPU to read the requested bytes and dump them to the | ||||
| screen. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| ==== IF: `POKE` <bbif-poke> | ||||
|  | ||||
| #_ifpagehead( | ||||
|   desc: "Writes values to the MPU's address space.", | ||||
|   syntax: [`POKE <ADDR> <BYTES>`], | ||||
|   params: ( | ||||
|     addr: "The base (low) address (two bytes) to start writing bytes from.", | ||||
|     bytes: "The bytes to write into memory separated by whitespace.", | ||||
|   ) | ||||
| ) | ||||
|  | ||||
| Poking memory causes the MPU to overwrite the bytes at `<ADDR>` with the bytes | ||||
| given in `<BYTES>`. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| ==== IF: `SREC` <bbif-srec> | ||||
|  | ||||
| #_ifpagehead( | ||||
|   desc: "Switches into Motorola S-Record receive mode.", | ||||
|   syntax: [`SREC`], | ||||
|   params: (), | ||||
| ) | ||||
|  | ||||
| Motorola S-Record mode is currently a stub. | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| === External Functions (EFs) <bbef-top> | ||||
|  | ||||
| External functions are any native user code that can be called with `CALL` (see | ||||
| @bbif-call). This mechanism is usable to run any code or routine in memory as | ||||
| though interactively using the MPU's `JSR` instruction. | ||||
|  | ||||
| == BUZBEE Reserved Memory Regions <res-mem> | ||||
|  | ||||
| BUZBEE uses memory in the 0200-02FF page. A table of the layout of this memory | ||||
| is provided. The memory is laid out in a packed structure starting at 0200. | ||||
|  | ||||
| #table( | ||||
|   columns: (auto, 1fr, auto), | ||||
|   inset: 10pt, | ||||
|   align: center, | ||||
|   fill: (_, y) => | ||||
|     if calc.odd(y) { luma(250) } | ||||
|     else { white }, | ||||
|   table.header( | ||||
|     [*Internal Name*], [*Size (Bytes)*], [*Description*] | ||||
|   ), | ||||
|   [`input`], | ||||
|   [128], | ||||
|   [Text input buffer], | ||||
|   [`cchinput`], | ||||
|   [2], | ||||
|   [Text input buffer character count], | ||||
|   [`tokens`], | ||||
|   [64], | ||||
|   [BUZBEE token buffer], | ||||
|   [`cbtokens`], | ||||
|   [2], | ||||
|   [Count of bytes in `tokens`], | ||||
|   [`scratch`], | ||||
|   [2], | ||||
|   [Internal scratch word used for some operations], | ||||
| ) | ||||
|  | ||||
| #pagebreak() | ||||
|  | ||||
| == BUZBEE Internals and Modding <bbinternals> | ||||
|  | ||||
| BUZBEE's interpreter works by "compiling" textual user commands into bytecode | ||||
| for more simply passing parameters to IFs (see @bbif-top). The way that works is | ||||
| the implementation dependent, but each hash is one byte (1B) in size, and | ||||
| corresponds to an IF token, which is the index of the hash. | ||||
|  | ||||
| BUZBEE's source, and the surrounding BIOS source is well commented, but a | ||||
| general summary of the control flow is provided here. | ||||
|  | ||||
| + BUZBEE sets up the prompt and input buffer with `NEWLINE` | ||||
| + BUZBEE enters an input processing loop that works with the CHIBI PC-09's | ||||
|   serial driver. | ||||
| + If no input is provided, restart. | ||||
| + BUZBEE makes a tokenizing pass over the input buffer. | ||||
| + BUZBEE attempts to execute the tokens, which may involve leaving the BUZBEE | ||||
|   loop, or in the event the IF returns, loops around and re-enters the BUZBEE | ||||
|   loop. | ||||
							
								
								
									
										62
									
								
								docs/style.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								docs/style.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| // Style conf function for CHIBI PC-09 projects | ||||
| #let conf( | ||||
|   title: none, | ||||
|   subtitle: none, | ||||
|   author: none, | ||||
|   doc, | ||||
| ) = { | ||||
|  | ||||
|   // Global page format | ||||
|   set page( | ||||
|     paper: "us-letter", | ||||
|     header: align(right, text(10pt, weight: "light")[#title]), | ||||
|     numbering: "1", | ||||
|   ) | ||||
|  | ||||
|   // Font settings | ||||
|   set text( | ||||
|     font: "New Computer Modern", | ||||
|     size: 12pt, | ||||
|   ) | ||||
|  | ||||
|   // Default paragraph settings | ||||
|   set par( | ||||
|     justify: true, | ||||
|     first-line-indent: 1cm, | ||||
|   ) | ||||
|  | ||||
|   // Heading numbering | ||||
|   set heading(numbering: "1.1") | ||||
|  | ||||
|   // Show table captions above tables | ||||
|   show figure.where(kind: table): set figure.caption(position: top) | ||||
|  | ||||
|   // Title page and TOC | ||||
|   page(header: none, footer: none)[ | ||||
|     // Emit title and subtitle page | ||||
|     #block(height: 60%)[ | ||||
|       #align(center + horizon, | ||||
|         block(text(22pt)[#title]) + | ||||
|         block(above: 2em)[#smallcaps[#subtitle]] + | ||||
|         block[Written by #author], | ||||
|       ) | ||||
|     ] | ||||
|     // Emit TOC | ||||
|     #pagebreak() | ||||
|     #outline() | ||||
|     #pagebreak() | ||||
|   ] | ||||
|  | ||||
|   // Heading formatting for doc, must come after title page and TOC | ||||
|   show heading: it => [ | ||||
|     CHAPTER | ||||
|     #counter(heading).display() | ||||
|     #it.body | ||||
|   ] | ||||
|  | ||||
|   // Emit doc | ||||
|   counter(page).update(1) // Reset counter for first real page | ||||
|   set align(left) | ||||
|   doc | ||||
| } | ||||
|  | ||||
| @@ -28,6 +28,6 @@ sed -e "s/<TAG>/$TAG/g" -e "s/<DATE>/$DATE/g" <<EOF > "$OUTFILE" | ||||
|  | ||||
| VERMSG | ||||
|   fcc "CHIBI PC-09 BOOT ROM <TAG>" | ||||
|   fcb \$0A | ||||
|   fcb \$0D,\$0A | ||||
|   fcn "BUILT <DATE>" | ||||
| EOF | ||||
|   | ||||
							
								
								
									
										15
									
								
								linkscript
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								linkscript
									
									
									
									
									
								
							| @@ -1,6 +1,19 @@ | ||||
| ; BIOS | ||||
| section RESET load 8000 | ||||
| section SERIAL | ||||
| section MEMTEST | ||||
|  | ||||
| ; BIOS Interface and Utilities | ||||
| section BIOSINT | ||||
|  | ||||
| ; BUZBEE Monitor | ||||
| section BUZBEE | ||||
| section BBHASHES | ||||
|  | ||||
| ; Onboard programs | ||||
| section MEMTEST load 9000 | ||||
|  | ||||
| ; Static Data | ||||
| section VECTORS high 100000 | ||||
| section VERSION high | ||||
|  | ||||
| entry 8000 | ||||
|   | ||||
							
								
								
									
										16
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								makefile
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| # Makefile for CHIBI PC-09 Firmware | ||||
|  | ||||
| .PHONY: generate all clean | ||||
| .PHONY: generate all clean docs | ||||
| .IGNORE: clean | ||||
| .DEFAULT_GOAL := all | ||||
|  | ||||
| @@ -13,7 +13,7 @@ TARGREC  := $(TARGET).s19 | ||||
| TARGROM  := $(TARGET).bin | ||||
| SRCDIR   := src/ | ||||
| BUILDDIR := build/ | ||||
| GENS     := $(SRCDIR)version.s | ||||
| GENS     := $(SRCDIR)version.s $(SRCDIR)bbhash.s | ||||
| SRCS     := $(wildcard $(SRCDIR)*.s) | ||||
| OBJS     := $(patsubst $(SRCDIR)%.s,$(BUILDDIR)%.o,$(SRCS)) | ||||
| INCS     := $(wildcard $(SRCDIR)*.inc) | ||||
| @@ -33,6 +33,9 @@ LDFLAGS := -f srec -m map.txt -s linkscript | ||||
| # Rules and Phony Targets | ||||
| # ------------------------------------------------------------------------------ | ||||
|  | ||||
| docs: docs/*.typ | ||||
| 	typst compile docs/firmware.typ | ||||
|  | ||||
| all: $(TARGROM) | ||||
|  | ||||
| # Fix srec into flashable bin file | ||||
| @@ -48,11 +51,18 @@ $(OBJS): $(BUILDDIR)%.o : $(SRCDIR)%.s | ||||
| 	-@mkdir -p $(BUILDDIR) | ||||
| 	$(AS) $(ASFLAGS) -o $@ $< | ||||
|  | ||||
| # Pseudo target for generation step | ||||
| generate: $(GENS) | ||||
|  | ||||
| $(GENS): | ||||
| # Run generation scripts | ||||
| $(GENS): bbmkhash | ||||
| 	./bbmkhash > src/bbhash.s | ||||
| 	./genver.sh | ||||
|  | ||||
| # Build bbmkcmds, used to generate src/cmds.s | ||||
| bbmkhash: bbmkhash.c | ||||
| 	cc -o $@ $< | ||||
|  | ||||
| clean: | ||||
| 	@echo 'Cleaning up intermediary files...' | ||||
| 	@rm -rv $(TARGROM) $(TARGREC) map.txt $(BUILDDIR) | ||||
|   | ||||
							
								
								
									
										8
									
								
								src/bbhash.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/bbhash.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| ; CHIBI PC-09 Machine Language Monitor -- BUZBEE Command Hash Table Symbols | ||||
| ; Copyright (c) 2025 Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
| ; vim: ft=asm | ||||
|  | ||||
| BBCHTC IMPORT | ||||
| BBCHT IMPORT | ||||
| @@ -1,7 +1,7 @@ | ||||
| ; CHIBI PC-09 Prototype #1 -- Memory Testing Routines Header
 | ||||
| ; CHIBI PC-09 Prototype #1 -- BIOS Interface Header
 | ||||
| ; Copyright (c) 2025 Amber Zeller, Gale Faraday | ||||
| ; Licensed under MIT | ||||
| 
 | ||||
| ; vim: ft=asm | ||||
| 
 | ||||
| RAMTEST IMPORT | ||||
| CHIBIO IMPORT | ||||
							
								
								
									
										50
									
								
								src/biosint.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/biosint.s
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| ; CHIBI PC-09 Prototype #1 Boot ROM -- BIOS Interface | ||||
| ; Copyright (c) 2024-2025 Amber Zeller, Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; CHIBI/O Stable BIOS Interface | ||||
| ;; | ||||
| ;; Called through SWI3 | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
|   SECTION BIOSINT | ||||
|  | ||||
|   EXPORT CHIBIO | ||||
|  | ||||
| ; CHIBI/O Entrypoint -- Stable, but defined by linkerscript $8800 | ||||
| ; @param A: Function ID | ||||
| CHIBIO | ||||
|   tfr a,d              ; 8-to-16 tfr, fill both a and b | ||||
|   clra                 ; Clear MSB | ||||
|   asld                 ; Convert to word offset | ||||
|   tfr d,x              ; Put in X for indexing mode | ||||
|   jmp [CHIBIOPTRTBL,x] ; Jump! | ||||
|  | ||||
| ; Jump table | ||||
| CHIBIOPTRTBL | ||||
|   fdb CIOPOUTCHAR ; serial/POUTCHAR wrapper | ||||
|   fdb CIOPOUTZSTR ; serial/POUTZSTR wrapper | ||||
|   fdb CIOPINCHAR  ; serial/CIOPINCHAR wrapper | ||||
|  | ||||
| ; POUTCHAR wrapper | ||||
| ; @param B: char to write | ||||
| CIOPOUTCHAR | ||||
|   tfr b,a | ||||
|   jsr POUTCHAR | ||||
|   rti | ||||
|  | ||||
| ; POUTZSTR wrapper | ||||
| ; @param X: start of zstring | ||||
| CIOPOUTZSTR | ||||
|   jsr POUTZSTR | ||||
|   rti | ||||
|  | ||||
| ; PINCHAR | ||||
| ; @return A: filled with char from RX buffer or NUL if no char is ready | ||||
| ; @return B: filled with LSR status codes masked with $9F | ||||
| CIOPINCHAR | ||||
|   jsr PINCHAR | ||||
|   rti | ||||
							
								
								
									
										7
									
								
								src/buzbee.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/buzbee.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| ; CHIBI PC-09 Machine Language Monitor -- BUZBEE Header | ||||
| ; Copyright (c) 2025 Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
| ; vim: ft=asm | ||||
|  | ||||
| BUZBEE IMPORT | ||||
							
								
								
									
										459
									
								
								src/buzbee.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								src/buzbee.s
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,459 @@ | ||||
| ; CHIBI PC-09 Machine Language Monitor -- BUZBEE | ||||
| ; Copyright (c) 2025 Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
|   INCLUDE "bbhash.inc" | ||||
|   INCLUDE "buzbee.inc" | ||||
|   INCLUDE "hardware.inc" | ||||
|   INCLUDE "serial.inc" | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Variables | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| BBIN_DEPTH     EQU $80 ; Input buffer depth | ||||
| BBTOKENS_DEPTH EQU $40 ; Token buffer depth | ||||
|  | ||||
|   SECTION BBVARS,bss | ||||
|  | ||||
| tagbbvar STRUCT | ||||
| input    rmb BBIN_DEPTH     ; Input buffer | ||||
| cchinput rmd 1              ; Input buffer char count | ||||
| tokens   rmb BBTOKENS_DEPTH ; Token buffer | ||||
| cbtokens rmd 1              ; Token buffer byte count | ||||
| scratch  rmd 1              ; Scratch word | ||||
|   ENDSTRUCT | ||||
|  | ||||
|   ORG $0200 | ||||
| BBVAR tagbbvar | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Main Loop | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
|   SECTION BUZBEE | ||||
|  | ||||
|   EXPORT BUZBEE | ||||
|  | ||||
| BUZBEE | ||||
|   lbsr NEWLINE       ; Setup the new input line and handle display. | ||||
|   bsr INPLOOP        ; Fill input buffer. | ||||
|   cmpy #0            ; No data? | ||||
|   beq BUZBEE         ;  Try again... | ||||
|   lbsr MKINSENSITIVE ; Make the input buffer case insensitive | ||||
|   lbsr TOKENIZE      ; Try to tokenize the input buffer | ||||
|   lbsr RUNIF         ; Execute token buffer, handling any errors | ||||
|   bra BUZBEE         ; Repeat | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Input Buffering and Handling Routines | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ; Fills input buffer with characters from the serial console. Sets Y to the | ||||
| ; offset in the input buffer of the last char read. | ||||
| INPLOOP | ||||
|   jsr PINCHAR          ; Try to read a char | ||||
|   cmpd #0              ; If no char keep waitin' | ||||
|   beq INPLOOP | ||||
|   bitb #UARTF_LSR_DR   ; Is there a char in A? | ||||
|   beq NOCHAR@ | ||||
|   cmpa #$1B            ; ESC? | ||||
|   beq HESC@            ;  Handle ESC | ||||
|   cmpa #$08            ; BS? | ||||
|   beq HBACKSPC@        ;  Backup a char | ||||
|   cmpa #$0D            ; CR? | ||||
|   beq HCR@             ;  Then terminate and parse input buffer | ||||
|   cmpy #BBIN_DEPTH     ; Are we at the end of the input buffer? | ||||
|   beq FULLBUF@         ; Handle the buffer being full | ||||
| ECHO@ | ||||
|   jsr POUTCHAR         ; Echo char back, this includes BS chars | ||||
|   sta BBVAR.input,y    ; Add it to the input buffer | ||||
|   leay 1,y | ||||
|   ; Fall through | ||||
| NOCHAR@ | ||||
|   ; Check for error condition, work based on The Serial Port release 19 | ||||
|   bitb #(UARTF_LSR_FIFO|UARTF_LSR_BI|UARTF_LSR_FE|UARTF_LSR_PE|UARTF_LSR_OE) | ||||
|   beq INPLOOP | ||||
|   bitb #UARTF_LSR_OE   ; Check for overrun error | ||||
|   beq NOOVER@ | ||||
|   PZSTR EM_OVERRUN | ||||
| NOOVER@ | ||||
|   bitb #UARTF_LSR_PE   ; Check for parity error | ||||
|   beq NOPARITY@ | ||||
|   PZSTR EM_PARITY | ||||
| NOPARITY@ | ||||
|   bitb #UARTF_LSR_FE   ; Check for framing error | ||||
|   beq NOFRAM@ | ||||
|   PZSTR EM_FRAMING | ||||
| NOFRAM@ | ||||
|   bitb #UARTF_LSR_FIFO ; Check for FIFO error | ||||
|   beq INPLOOP          ; Loop over | ||||
|   PZSTR EM_FIFO | ||||
|   bra INPLOOP          ; Loop over | ||||
| HCR@ | ||||
|   sty BBVAR.cchinput   ; Store buffer length | ||||
|   rts | ||||
| HESC@ | ||||
|   lda #'^              ; Print a char that signifies that ESC was pressed | ||||
|   jsr POUTCHAR | ||||
|   ldy #0               ; On return we cmpy #0 and if eq then newline | ||||
|   rts | ||||
| HBACKSPC@ | ||||
|   clrb                 ; Clear last char | ||||
|   leay -1,y | ||||
|   stb BBVAR.input | ||||
|   bra ECHO@            ; Echo the char in A | ||||
| FULLBUF@ | ||||
|   lda #$07             ; ASCII BEL | ||||
|   jsr POUTCHAR | ||||
|   lbra INPLOOP | ||||
|  | ||||
| ; Handle new lines; prints a new prompt and then clears the input buffer | ||||
| NEWLINE | ||||
|   PZSTR PROMPTLINE  ; Print prompt line | ||||
| CLRIN               ; Label to just clear input buffer without newline | ||||
|   clra              ; Init A and X | ||||
|   ldx #0 | ||||
| NEXT@ | ||||
|   sta BBVAR.input,x ; Clear input buffer | ||||
|   leax 1,x | ||||
|   cmpx #BBIN_DEPTH | ||||
|   blo NEXT@ | ||||
|   ldy #0            ; Reset buffer fill pointer | ||||
|   rts | ||||
|  | ||||
| ; Makes the input buffer case insensitive | ||||
| MKINSENSITIVE | ||||
| NEXTC@ | ||||
|   lda BBVAR.input,x | ||||
|   cmpa #'z            ; Is the char outside the lowercase range? | ||||
|   bhi NOTLCASE@       ;  Yes? Skip offset part | ||||
|   cmpa #'a            ; Again on the other side of the range | ||||
|   blo NOTLCASE@ | ||||
|   anda #$DF           ; -32 | ||||
| NOTLCASE@ | ||||
|   leax 1,x            ; Ready next char | ||||
|   cmpx BBVAR.cchinput ; Are we at the end? | ||||
|   bne NEXTC@          ;  No? Loop | ||||
|   rts | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; Hex Conversion and Printing Routines | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ; Prints a byte in A | ||||
| ; @param A: byte to print | ||||
| PBYTE | ||||
|   pshs b | ||||
|   tfr a,b      ; Transfer lower nybble into B | ||||
|   andd #$F00F  ; Mask and adjsut | ||||
|   asra | ||||
|   asra | ||||
|   asra | ||||
|   asra | ||||
|   anda #$0F | ||||
|   ora #'0      ; Add '0' to offset to digits | ||||
|   cmpa #$3A    ; Hex? ':' '9'+1 | ||||
|   blo SKIPA@ | ||||
|   adca #6      ; Hex offset | ||||
| SKIPA@ | ||||
|   jsr POUTCHAR ; Print char in A | ||||
|   andb #$0F | ||||
|   orb #'0      ; Add '0' to offset to digits | ||||
|   cmpb #$3A    ; Hex? ':' '9'+1 | ||||
|   blo SKIPB@ | ||||
|   adcb #6      ; Hex offset | ||||
| SKIPB@ | ||||
|   tfr b,a      ; Print char in B | ||||
|   jsr POUTCHAR | ||||
|   puls b       ; Restore B | ||||
|   rts | ||||
|  | ||||
| ; Converts a hexadecimal sequence into a byte value | ||||
| ; @param D: hex representation of a byte with A: MSD B: LSD | ||||
| ; @return A: returned byte value | ||||
| ; NOTE: Conversion logic credit to Wozniak. This code unrolled for speed. | ||||
| HEX2BYT | ||||
|   eora #$B0         ; Map digits to 0-9 | ||||
|   cmpa #9+1         ; Is it a decimal? | ||||
|   blo AISDEC@       ;  Yes? skip hex adjust | ||||
|   adca #$88         ; Map 'A'-'F' to $FA-$FF | ||||
|   cmpa #$FA         ; Hex char? | ||||
|   blo BADHEX@       ;  No? Print error | ||||
| AISDEC@ | ||||
|   asla              ; Shift MSD into upper nybble of A | ||||
|   asla | ||||
|   asla | ||||
|   asla | ||||
| ; Do B part | ||||
|   eorb #$B0         ; Map digits to 0-9 | ||||
|   cmpa #9+1         ; Is it a decimal? | ||||
|   blo BISDEC@       ; Yes? skip hex adjust | ||||
|   adcb #$88         ; Map 'A'-'F' to $FA-$FF | ||||
|   andb #$0F         ; Mask high nybble | ||||
|   cmpb #$0A         ; Hex char? | ||||
|   blo BADHEX@       ;  No? Print error | ||||
| BISDEC@ | ||||
|   stb BBVAR.scratch ; Store low nybble in scratch buffer | ||||
|   ora BBVAR.scratch ; Combine the nybbles | ||||
|   rts | ||||
| BADHEX@ | ||||
|   PZSTR EM_BADHEX   ; Print an error message | ||||
|   clrd              ; Prevent RUNIF from executing | ||||
|   std BBVAR.cbtokens | ||||
|   rts | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Tokenizing Routines | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ; Attempts to parse the input buffer into tokens depending on the command | ||||
| TOKENIZE | ||||
|   ldd BBVAR.cchinput   ; Do we have input to work with? | ||||
|   cmpd #4              ; Do we have even enough space for a string command | ||||
|   blo TOKFAIL@         ;  No? GTFO | ||||
|   ldy #0               ; Initialize Y; used to track current position in BBVAR.input | ||||
|   ldx #0               ; Initialize X; used to track position in BBVAR.tokens | ||||
|   bsr SKIPTONEXTC      ; Get the next non-whitespace char | ||||
|   bsr MKCMDSUM         ; Hash the first four non-whitespace chars | ||||
|   bsr HASH2TOKEN       ; Try to turn that hash into a proper token | ||||
|   bcs TOKFAIL@ | ||||
|   bra STTOK@           ; Store token | ||||
| NEXTHEX@               ; Next hex token | ||||
|   bsr SKIPTONEXTC      ; Skip to next whitespace | ||||
|   ldd BBVAR.input,y    ; Get hex value (two digits) | ||||
|   bsr HEX2BYT          ; Convert hex value to byte value | ||||
| STTOK@ | ||||
|   sta BBVAR.tokens,x   ; Store curent token | ||||
|   leax 1,x             ; Advance to next token | ||||
|   cmpx #BBTOKENS_DEPTH ; Is this next token in bounds? | ||||
|   beq FULLBUF@         ;  No? handle a full buffer | ||||
|   bra NEXTHEX@         ; Try to turn the next character into a hex value | ||||
| FULLBUF@ | ||||
|   PZSTR EM_FULLTOKBUF  ; Print an error message | ||||
|   clrd                 ; Say we wrote no tokens | ||||
|   std BBVAR.cbtokens | ||||
|   rts | ||||
| TOKFAIL@ | ||||
|   PZSTR EM_TOKFAIL     ; Print tokenization fail | ||||
|   clrd                 ; Say we wrote no tokens | ||||
|   std BBVAR.cbtokens | ||||
|   rts | ||||
|  | ||||
| ; Converts a runtime command hash into a portable token. Command tokens are | ||||
| ; indexes into BBCHT, which is generated at compile-time | ||||
| ; @param A: runtime hash | ||||
| ; @return A: output token | ||||
| ; @return CC.C: set if error state, cleared otherwise | ||||
| HASH2TOKEN | ||||
|   pshs x           ; Preserve & init X; other routines in this group use it | ||||
|   ldx #0 | ||||
| NEXTHASH@ | ||||
|   cmpa BBCHT,x     ; Is this hash our hash? | ||||
|   beq THISHASH@    ;  Yes? turn it into a token | ||||
|   leax 1,x         ; Begin considering next hash | ||||
|   cmpx BBCHTC      ; Is the next hash even in the table? | ||||
|   blo NEXTHASH@    ;  Yes? try this next hash, No? fall through | ||||
|   PZSTR EM_BADHASH CALL; Print an error message to the user | ||||
|   puls x | ||||
|   orcc #1          ; Set CC.C to indicate error | ||||
|   rts | ||||
| THISHASH@ | ||||
|   puls x | ||||
|   andcc #$FE       ; Clear CC.C to indicate success | ||||
|   rts | ||||
|  | ||||
| ; Makes a hash of four chars in BBIN starting at offset X | ||||
| ; @param Y: offset in BBIN to read the four chars from | ||||
| ; @return A: resulting hash | ||||
| ; @return Y: offset after hash processing | ||||
| MKCMDSUM | ||||
|   pshs b | ||||
|   ldb #4             ; Loop over four chars | ||||
|   clra               ; Initialize accumulator | ||||
| NEXTC@ | ||||
|   suba BBVAR.input,y ; Subtract current char from accumulator | ||||
|   leax 1,y           ; Next char | ||||
|   decb               ; Reduce count | ||||
|   cmpb #0            ; Are we at the end? | ||||
|   bne NEXTC@         ;  No? loop | ||||
|   puls b | ||||
|   rts | ||||
|  | ||||
| ; Skips "whitespace" to the next semantic char | ||||
| ; @param Y: current index in text buffer | ||||
| ; @return Y: resulting index in text buffer | ||||
| SKIPTONEXTC | ||||
|   lda BBVAR.input,y ; Get our char? | ||||
|   cmpa #$20         ; SPACE or control char? | ||||
|   bhi EXIT@         ;  Yes? End | ||||
|   leay 1,y          ; Iterate next char | ||||
|   bra SKIPTONEXTC | ||||
| EXIT@ | ||||
|   rts | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE IF Handling Functions | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ; Executes a command based on the initial token | ||||
| ; @corrupts B | ||||
| ; @return X: command data table index | ||||
| RUNIF | ||||
|   clrd             ; Do we have any tokens? | ||||
|   cmpd BBVAR.cbtokens | ||||
|   beq NOTOK@ | ||||
|   ldx #0           ; Counting up from zero | ||||
|   lda BBVAR.tokens ; Load token | ||||
|   tfr a,d          ; Get the index in D | ||||
|   clra | ||||
|   asld             ; Cheaply << to get *2, pointer size | ||||
|   tfr d,x          ; Move to X so we can use indexed mode with the offset | ||||
|   jmp [IFPTRTBL,x] ; Select IF | ||||
| NOTOK@ | ||||
|   rts | ||||
|  | ||||
| ; IF pointer table | ||||
| IFPTRTBL | ||||
|   fdb IFCALL | ||||
|   fdb IFHELP | ||||
|   fdb IFPEEK | ||||
|   fdb IFPOKE | ||||
|   fdb IFSREC | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Internal Command Functions | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| ; Call a pointer | ||||
| IFCALL | ||||
|   ldd BBVAR.cbtokens   ; Only jump if three tokens given | ||||
|   cmpd #3 | ||||
|   lbne INVALIDARG | ||||
|   jsr [BBVAR.tokens+1] ; Make our jump (doesn't implicitly return) | ||||
|   rts | ||||
|  | ||||
| ; Print out a help message | ||||
| IFHELP | ||||
|   PZSTR HELP_MSG | ||||
|   rts | ||||
|  | ||||
| ; Peek memory | ||||
| IFPEEK | ||||
|   ldd BBVAR.cbtokens   ; One 16-bit token given, single peek | ||||
|   cmpd #3 | ||||
|   lblo INVALIDARG      ; Not enough args given | ||||
|   bhi SELTYPE@         ; Select forward or backward peek | ||||
| SINGLE@ | ||||
|   lda [BBVAR.tokens+1] ; Get byte | ||||
|   lbsr PBYTE           ; Print peek byte | ||||
|   rts | ||||
| SELTYPE@ | ||||
|   ldd BBVAR.cbtokens   ; Have enough tokens? | ||||
|   cmpd #5 | ||||
|   lbne INVALIDARG      ;  No? bounce out | ||||
|   ldd BBVAR.tokens+1   ; Are we forwards (BASE < HIGH)? | ||||
|   cmpd BBVAR.tokens+3 | ||||
|   beq SINGLE@          ; Gracefully handle BASE == HIGH | ||||
|   bhi INVALIDARG       ; Malformed if BASE > HIGH | ||||
|   ldx BBVAR.tokens+1   ; Get BASE | ||||
| NEXT@ | ||||
|   lda ,x+              ; Get the next byte | ||||
|   lbsr PBYTE           ; Print our byte | ||||
|   cmpx BBVAR.tokens+3  ; Are we at <HIGH> yet? | ||||
|   bne NEXT@            ;  No? loop | ||||
|   rts | ||||
|  | ||||
| ; Poke bytes into memory | ||||
| ; NOTE: Blocks could also use 6309 TFM instruction | ||||
| IFPOKE | ||||
|   ldx BBVAR.cbtokens      ; Make sure we have enough tokens | ||||
|   cmpx #4 | ||||
|   lblo INVALIDARG | ||||
|   leax -3,x               ; Get count of bytes to write into X | ||||
|   ldy #0                  ; Setup Y for indexing | ||||
| NEXTB@ | ||||
|   lda BBVAR.tokens+3,y    ; Get source byte to copy | ||||
|   sta [BBVAR.tokens+1,y]  ; Copy byte | ||||
|   leay +1,y               ; Increment memory indexer | ||||
|   leax -1,x               ; Decement byte count | ||||
|   cmpx #0                 ; Are we at our last byte? | ||||
|   bhi NEXTB@              ;  No? loop | ||||
|   rts | ||||
|  | ||||
| ; Placeholder function labels to make assembler happy before git commit | ||||
| IFSREC | ||||
|   rts | ||||
|  | ||||
| ; Invalid argument IF tail | ||||
| INVALIDARG | ||||
|   PZSTR EM_BADARG | ||||
|   rts | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; BUZBEE Strings and Fixed Data | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| HELP_MSG | ||||
|   fcc "-- BUZBEE HELP --" | ||||
|   fcb $0D,$0A | ||||
|   fcc "Available Commands:" | ||||
|   fcb $0D,$0A | ||||
|   fcc "CALL <PTR> - Call the pointer given in <PTR> as a subroutine." | ||||
|   fcb $0D,$0A | ||||
|   fcc "HELP [CMD] - Display help, command optional." | ||||
|   fcb $0D,$0A | ||||
|   fcc "PEEK <BASE> [<HIGH>] - Read memory at <BASE> to <HIGH>." | ||||
|   fcb $0D,$0A | ||||
|   fcc "POKE <ADDR> <BYTES> - Overwrite memory with <BYTES> starting at <BASE>." | ||||
|   fcb $0D,$0A | ||||
|   fcc "SREC - Enter Motorola S-Record entry mode." | ||||
|   fcb $0D,$0A | ||||
|   fcb $00 | ||||
|  | ||||
| PROMPTLINE | ||||
|   fcb $0D,$0A,$25,$00 ; CR LF '%' NUL | ||||
|  | ||||
| EM_OVERRUN | ||||
|   fcc "!!! UART Overrun Error !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_PARITY | ||||
|   fcc "!!! UART Parity Error !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_FRAMING | ||||
|   fcc "!!! UART Framing Error !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_FIFO | ||||
|   fcc "!!! UART FIFO Error !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_BADHASH | ||||
|   fcc "!!! Bad Command Hash !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_BADARG | ||||
|   fcc "!!! Malformed Arguments !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_TOKFAIL | ||||
|   fcc "!!! Tokenization Failure !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_BADHEX | ||||
|   fcc "!!! Malformed Hex Value !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| EM_FULLTOKBUF | ||||
|   fcc "!!! Token Buffer Overrun !!!" | ||||
|   fcb $0D,$0A,$00 | ||||
| @@ -1,24 +1,25 @@ | ||||
| ; CHIBI PC-09 Prototype #1 Boot ROM -- Memory Testing Routines
 | ||||
| ; CHIBI PC-09 Prototype #1 Boot ROM -- Onboard Programs or BUZBEE "EFs"
 | ||||
| ; Copyright (c) 2024-2025 Amber Zeller, Gale Faraday
 | ||||
| ; Licensed under MIT
 | ||||
| 
 | ||||
| ; These are onboard programs with fixed locations in the linkerscript for
 | ||||
| ; starting from a machine language monitor
 | ||||
| 
 | ||||
|   INCLUDE "hardware.inc" | ||||
|   INCLUDE "serial.inc" | ||||
| 
 | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | ||||
| ;;
 | ||||
| ;; Memory Testing Routines
 | ||||
| ;; Memory Testing Routine
 | ||||
| ;;
 | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | ||||
| 
 | ||||
|   SECTION MEMTEST | ||||
| 
 | ||||
|   EXPORT RAMTEST | ||||
| 
 | ||||
| ; RAM testing routine. Ported to 6809 from 6800, based on source for ROBIT-2 for
 | ||||
| ; MIKBUG.
 | ||||
| RAMTEST | ||||
|   ldx #SRAM_BASE | ||||
| ROBIT | ||||
|   ldx #STACK_TOP+1     ; bottom of testable SRAM, $0200
 | ||||
| AGAIN@                 ; Store 1 in memory
 | ||||
|   lda #1               ; Set [X] to 1
 | ||||
|   sta 0,x | ||||
| @@ -41,4 +42,17 @@ ERR@                   ; Write out error indicator | ||||
| PASS@                  ; Pass test
 | ||||
|   ldb #'P | ||||
|   jsr POUTCHAR | ||||
|   rts | ||||
|   bra HALT | ||||
| 
 | ||||
| ; Prints a message about completing a memory test prompting the user to reset
 | ||||
| ; then puts the MPU in a loop where it only responds to interrupts, effectively
 | ||||
| ; halting the CHIBI
 | ||||
| HALT | ||||
|   PZSTR MSG_FINISH | ||||
| LOOP@
 | ||||
|   sync | ||||
|   bra LOOP@
 | ||||
| 
 | ||||
| MSG_FINISH | ||||
|   fcc "Memory test finished! Please reset" | ||||
|   fcb $0D,$0A,$00 | ||||
							
								
								
									
										30
									
								
								src/reset.s
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/reset.s
									
									
									
									
									
								
							| @@ -2,9 +2,9 @@ | ||||
| ; Copyright (c) 2024-2025 Amber Zeller, Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
|   INCLUDE "buzbee.inc" | ||||
|   INCLUDE "hardware.inc" | ||||
|   INCLUDE "serial.inc" | ||||
|   INCLUDE "memtest.inc" | ||||
|   INCLUDE "version.inc" | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| @@ -22,8 +22,8 @@ RESET | ||||
|  | ||||
| CLRSTACK | ||||
|   ; Initialize the system stack | ||||
|   lda #$00           ; Initialize A & X to zero out the stack | ||||
|   ldx #$0000 | ||||
|   clra               ; Init A & X to zero out the stack | ||||
|   ldx #0 | ||||
| NEXT@ | ||||
|   sta STACK_BOTTOM,x ; Write a zero and progress to the next byte | ||||
|   leax 1,x | ||||
| @@ -35,13 +35,21 @@ BOOTSCR | ||||
|   lda #13      ; 9600 baud | ||||
|   ldb #%11     ; 8N1 | ||||
|   jsr INITUART ; Initialize serial console | ||||
|   ldx #VERMSG  ; Print version information | ||||
|   jsr POUTZSTR | ||||
|   PZSTR VERMSG ; Since we know the addr of VERMSG at link time we can avoid | ||||
|                ; calling out to CHIBIO | ||||
|  | ||||
| ; Progress to POST | ||||
| POST | ||||
|   jsr RAMTEST | ||||
| ; Hand off control to the BUZBEE monitor and print notification of leaving the | ||||
| ; firmware | ||||
| ENTERMON | ||||
|   PZSTR TXTRUN ; Print run message | ||||
|   jmp BUZBEE   ; Jump into a monitor program | ||||
|  | ||||
| HALT | ||||
|   sync                 ; Halt and wait for interrupts | ||||
|   bra HALT | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; | ||||
| ;; Text/Resources for Reset Handler | ||||
| ;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| TXTRUN | ||||
|   fcc "<3RUN<3" | ||||
|   fcb $0D,$0A,$00 | ||||
|   | ||||
| @@ -7,3 +7,12 @@ | ||||
| INITUART IMPORT | ||||
| POUTCHAR IMPORT | ||||
| POUTZSTR IMPORT | ||||
| PINCHAR  IMPORT | ||||
|  | ||||
| ; POUTZSTR wrapper macro | ||||
| PZSTR MACRO | ||||
|   pshs x | ||||
|   ldx #\1 | ||||
|   jsr POUTZSTR | ||||
|   puls x | ||||
|   ENDM | ||||
|   | ||||
							
								
								
									
										78
									
								
								src/serial.s
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/serial.s
									
									
									
									
									
								
							| @@ -15,6 +15,7 @@ | ||||
|   EXPORT INITUART | ||||
|   EXPORT POUTCHAR | ||||
|   EXPORT POUTZSTR | ||||
|   EXPORT PINCHAR | ||||
|  | ||||
| ; Initializes the UART with LCR settings and a BAUD rate from DIVISORS. | ||||
| ; ACCA: Index of the divsor to use in DIVISORS | ||||
| @@ -30,41 +31,11 @@ INITUART | ||||
|   stb UART_LCR  ; Write LCR | ||||
|   lda #(UARTF_FCR_FE|UARTF_FCR_RFR|UARTF_FCR_XFR) ; FIFO disable and clear | ||||
|   sta UART_FCR | ||||
|   lda #0 | ||||
|   clra | ||||
|   sta UART_IER  ; Polled mode | ||||
|   sta UART_MCR  ; Reset DTR, RTS | ||||
|   rts | ||||
|  | ||||
| ; Prints a character in polled non-FIFO mode (INITUART state). | ||||
| ; ACCA: char to write | ||||
| POUTCHAR | ||||
|   pshs a       ; Preserve char | ||||
| NOTREADY@ | ||||
|   lda UART_LSR ; Wait until LSR.THRE == 1 then write char | ||||
|   bita UARTF_LSR_THRE | ||||
|   beq NOTREADY@ | ||||
|   puls a       ; Restore char | ||||
|   sta UART_THR ; Write char | ||||
|   rts | ||||
|  | ||||
| ; Prints a null terminated string in polled non-FIFO mode (INITUART state). | ||||
| ; X: start of zstring | ||||
| POUTZSTR | ||||
|   pshs a,b     ; Preserve A and B | ||||
| NEXTC@ | ||||
|   ldb ,x+      ; Get next char from X and increment X for next time | ||||
|   cmpb #$00    ; Make sure that we aren't at a terminator | ||||
|   beq END@ | ||||
| NOTREADY@ | ||||
|   lda UART_LSR ; Wait until LSR.THRE == 1 then write char | ||||
|   bita UARTF_LSR_THRE | ||||
|   beq NOTREADY@ | ||||
|   stb UART_THR ; Write char | ||||
|   bra NEXTC@   ; Iter to next char | ||||
| END@ | ||||
|   puls b,a     ; Restore A and B | ||||
|   rts | ||||
|  | ||||
| ; UART baud rate divisors | ||||
| DIVISORS | ||||
|   fdb $0900 ; 50 baud | ||||
| @@ -82,3 +53,48 @@ DIVISORS | ||||
|   fdb $0010 ; 7200 baud | ||||
|   fdb $000C ; 9600 baud | ||||
|   fdb $0006 ; 19200 baud | ||||
|  | ||||
| ; Prints a character in polled non-FIFO mode (INITUART state). | ||||
| ; ACCA: char to write | ||||
| POUTCHAR | ||||
|   pshs a       ; Preserve char | ||||
| NOTREADY@ | ||||
|   lda UART_LSR ; Wait until LSR.THRE == 1 then write char | ||||
|   bita #UARTF_LSR_THRE | ||||
|   beq NOTREADY@ | ||||
|   puls a       ; Restore char | ||||
|   sta UART_THR ; Write char | ||||
|   rts | ||||
|  | ||||
| ; Prints a null terminated string in polled non-FIFO mode (INITUART state). | ||||
| ; X: start of zstring | ||||
| POUTZSTR | ||||
|   pshs a,b     ; Preserve A and B | ||||
| NEXTC@ | ||||
|   ldb ,x+      ; Get next char from X and increment X for next time | ||||
|   cmpb #$00    ; Make sure that we aren't at a terminator | ||||
|   beq END@ | ||||
| NOTREADY@ | ||||
|   lda UART_LSR ; Wait until LSR.THRE == 1 then write char | ||||
|   bita #UARTF_LSR_THRE | ||||
|   beq NOTREADY@ | ||||
|   stb UART_THR ; Write char | ||||
|   bra NEXTC@   ; Iter to next char | ||||
| END@ | ||||
|   puls b,a     ; Restore A and B | ||||
|   rts | ||||
|  | ||||
| ; Reads a char in polled mode non-FIFO mode (INITUART state). | ||||
| ; A: Filled with char from RX buffer or NUL ($00) if no char is ready | ||||
| ; B: Filled with LSR status codes masked with $9F | ||||
| PINCHAR | ||||
|   ldb UART_LSR       ; See if a char is ready | ||||
|   ; Mask of possible UART error codes | data ready flag ($9F) | ||||
|   andb #(UARTF_LSR_DR|UARTF_LSR_OE|UARTF_LSR_PE|UARTF_LSR_FE|UARTF_LSR_BI|UARTF_LSR_FIFO) | ||||
|   bitb #UARTF_LSR_DR ; Check for char | ||||
|   beq NOCHAR@ | ||||
|   lda UART_RBR       ; Pull char from RX buffer | ||||
|   rts | ||||
| NOCHAR@ | ||||
|   clra               ; Fill A with '\0'. | ||||
|   rts | ||||
|   | ||||
							
								
								
									
										17
									
								
								src/vecs.s
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/vecs.s
									
									
									
									
									
								
							| @@ -2,6 +2,7 @@ | ||||
| ; Copyright (c) 2024-2025 Amber Zeller, Gale Faraday | ||||
| ; Licensed under MIT | ||||
|  | ||||
|   INCLUDE "biosint.inc" | ||||
|   INCLUDE "reset.inc" | ||||
|  | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| @@ -13,11 +14,11 @@ | ||||
|   SECTION VECTORS | ||||
|  | ||||
| VECTORS | ||||
|   fdb $0000 ; Reserved | ||||
|   fdb $0000 ; SWI3 | ||||
|   fdb $0000 ; SWI2 | ||||
|   fdb $0000 ; FIRQ | ||||
|   fdb $0000 ; IRQ | ||||
|   fdb $0000 ; SWI | ||||
|   fdb $0000 ; NMI | ||||
|   fdb RESET ; Reset | ||||
|   fdb $0000  ; Exception | ||||
|   fdb CHIBIO ; SWI3 | ||||
|   fdb $0000  ; SWI2 | ||||
|   fdb $0000  ; FIRQ | ||||
|   fdb $0000  ; IRQ | ||||
|   fdb $0000  ; SWI | ||||
|   fdb $0000  ; NMI | ||||
|   fdb RESET  ; Reset | ||||
|   | ||||
		Reference in New Issue
	
	Block a user