Skip to content

Instantly share code, notes, and snippets.

@Zardoz89
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Zardoz89/f98e002377e1a74bb79d to your computer and use it in GitHub Desktop.
Save Zardoz89/f98e002377e1a74bb79d to your computer and use it in GitHub Desktop.
Ideas for Trillek computer firmware
The idea is include a small set of functions to handle an TDA text buffer.
Could made in two ways :
1) Using "static" ram vars of cursor and base address. This make only usefull to control a single TDA screen.
2) Using a pointer to an "struct" with base address and cursor data, so could be use with multiple TDA screens. The firmware defines one of this structs on his ram vars for the primary graphics device, so it's used to print firmware messages.
Data on RAM to handle the text buffer :
- base_address (dword) : Were begins the text buffer (If we use option 1, this is now on the RAM vars)
- max_cols (ubyte) : How many columns (actually 40, but future graph cards, could allow more columns)
- max_rows (ubyte) : At what row, the cursor must wrap to 0 (usually 30)
- col (ubyte) : Actual column of the cursor
- row (ubyte) : Actual row of the cursor
Note that a uword row_col unpacks/packs to separate row and col with col being the LSB and row being MSB
Posible subrutines list :
Note: I use C like syntax, but this functions would use and set registers. Also, some functions would reuse code from others falling or jumping to it, for example puts would use putc
"Must" subrutines
- putc (ubyte c) : Puts a character on the text buffer. Move cursors to the next position
- puts (ubyte* str, word len) : Puts a string on the text buffer. Move cursor to the end of the string. (reuse internally puts)
- setatr_at (ubyte atr, uword col_row) : Sets attribute on the text buffer at col, row
- putdec_dw (unsigned dword val) : Write on decimal a double word value. Increases cursos the necesary positions. (reuse internally putc)
- puthex (ubyte val) : Write the LSB half byte on hexadecimal and increases cursor by one. (reuse internally putc)
- put_ubyte (ubyte val) : Writes a byte on hexadecimal (without 0x). Increases cursor by two positions. (reuse internally puthex)
- put_uword and put_udword : " Same that put_ubyte, reusing previus subrutine...
Why ?
putc/puts it's obvius why there are.
setatr_at it's to allow to change the default black on white colors (for example to make more noticiable an error)
putdec_dw at least to show how many ram there is.
put_ubyte & related would be necesary for the code machine monitor or to display a device list. puthex is a internal subrutine.
"Optional" subrutines
- ubyte getc_at (word col_row) : Gets a character from the text buffer at col & row
- uchar geta_at (word col_row) : Gets attribute from the text buffer at col, row
- word getcursor () : get/set col&row could be read/set directly on row and col vars, but could be an macro or small subrutine
- setcursor (uword col_row) : "
- putac (uword atrc) : Puts a character with color attribute on the text buffer. Move cursors to the next position
- putac_at (uword atrc, uchar col, uchar row) : Puts a character with color attribute on the text buffer at col, row
- word getac_at (uword col_row) : Gets a character with attribute from the text buffer at col, row
- putuword (uword val) : Writes a word on hexadecimal. ... (reuses internally putubyte)
- putudword (unsigned dword val) : Writes a double word on hexadecimal. ... (reuses internally putuword)
-----------------------------------------------------
; textbuf_struct
; .dd textbuf
; .db max_cols
; .db max_rows
; .db col
; .db row
; %r0 Ptr to textbuf_struct
; %r1 char to put on it
PUTC:
; Gets cursor and calcs offset
LOADB %r5, %r0, 6 ; Grabs column
LLS %r2, %r5, 1 ; Column x2, as we use a word for a attribute/char pair
LOADB %r3, %r0, 4 ; Grab max columns
LLS %r3, %r3, 1 ; Max Column x2
LOADB %r4, %r0, 7 ; Grab row
MUL %r6, %r4, %r3
ADD %r6, %r6, %r1 ; offset = col*2 + row * max_col*2
; NOTE: do 2*(col + row * max_col)
LOAD %r2, %r0 ; Base address of text buffer
STOREB %r2, %r6, %r1 ; base_address[offset] = character
ADD %r5, %r5, 1 ; Increase column
IFL %r5, %r3 ; If not wraps colum, end
JMP PUTC_END
MOV %r5, 0
ADD %r4, %r4, 1 ; Increase row
LOADB %r3, %r0, 5 ; Grab max rows
IFL %r4, %r3 ; If not wraps row, end
JMP PUTC_END
MOV %r4, 0
PUTC_END:
STORE %r0, 6, %r5 ; Writes to ram the new cursor position
STORE %r0, 7, %r4 ; row
RET
The built in firmware of the Trillek computer could:
1) Do a quick check of how much RAM the computer has.
2) Search for devices and store their info in RAM.
3) Set up a monitor and keyboard, getting by default the monitor and keyboard with the lowest slot number.
In future, it could try to get from NVRAM which monitor and keyboard to use.
4) Print basic information about the computer such as total RAM, CPU speed, number of devices found and
hardware info.
5) If there is a floppy drive with a floppy disk, try to boot from it. It there are many, it would use the
floppy drive with the lowest slot.
In future, it could try to get from NVRAM a boot-up search sequence.
6) If boot fails or there isn't a floppy drive, then it could launch a machine code monitor or a BASIC
interpreter.
Firmware devices table :
The table consists on a byte to indicate how many devices are connected in total, and how long is the table (total_devices variable).
The table itself is aligned to 4 byte boundary, as every entry takes 4 bytes and we can use LOAD to reach a single entry.
Each entry is :
dev_slot: .db
dev_type: .db
Why ? We need to know on what slots are all connected devices, and we can reuse this table to know what of these devices are a graphics card or a keyboard, so we can setup it. Later, we can use an index to designated what graphics card and keyboard are setup by the firmware.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment